2698 lines
40 KiB
HTML
2698 lines
40 KiB
HTML
<HTML
|
|
><HEAD
|
|
><TITLE
|
|
>Examples</TITLE
|
|
><META
|
|
NAME="GENERATOR"
|
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
|
|
REL="HOME"
|
|
TITLE="VB6 To Tcl mini-HOWTO"
|
|
HREF="index.html"><LINK
|
|
REL="PREVIOUS"
|
|
TITLE="Introduction"
|
|
HREF="intro.html"><LINK
|
|
REL="NEXT"
|
|
TITLE="Getting More Information"
|
|
HREF="more.html"></HEAD
|
|
><BODY
|
|
CLASS="SECT1"
|
|
BGCOLOR="#FFFFFF"
|
|
TEXT="#000000"
|
|
LINK="#0000FF"
|
|
VLINK="#840084"
|
|
ALINK="#0000FF"
|
|
><DIV
|
|
CLASS="NAVHEADER"
|
|
><TABLE
|
|
SUMMARY="Header navigation table"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
CELLPADDING="0"
|
|
CELLSPACING="0"
|
|
><TR
|
|
><TH
|
|
COLSPAN="3"
|
|
ALIGN="center"
|
|
>VB6 To Tcl mini-HOWTO</TH
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="left"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="intro.html"
|
|
ACCESSKEY="P"
|
|
>Prev</A
|
|
></TD
|
|
><TD
|
|
WIDTH="80%"
|
|
ALIGN="center"
|
|
VALIGN="bottom"
|
|
></TD
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="right"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="more.html"
|
|
ACCESSKEY="N"
|
|
>Next</A
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"></DIV
|
|
><DIV
|
|
CLASS="SECT1"
|
|
><H1
|
|
CLASS="SECT1"
|
|
><A
|
|
NAME="EXAMPLES"
|
|
></A
|
|
>2. Examples</H1
|
|
><DIV
|
|
CLASS="TABLE"
|
|
><A
|
|
NAME="AEN45"
|
|
></A
|
|
><P
|
|
><B
|
|
>Table 1. Differences</B
|
|
></P
|
|
><TABLE
|
|
BORDER="1"
|
|
CLASS="CALSTABLE"
|
|
><TBODY
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
>VB6 </TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="CENTER"
|
|
VALIGN="TOP"
|
|
> Tcl/Tk 8.3 </TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Notes/differences </TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim a as integer
|
|
dim b as integer
|
|
a=1 : b=0</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
</P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set a 1; set b 0
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
</P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Separator for multiple commands per line. Tcl uses a semicolon.
|
|
Multiple commands per line is generally considered bad form, but
|
|
the semicolon is also used to implement partial-line comments, so
|
|
it is illustrated here.
|
|
</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> ' this is a whole line
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> # this is a whole line
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Full-line comment. Neither language requires a space after the
|
|
comment marker.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim a as integer
|
|
a=1 'this is a partial-line comment
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set a 1 ;# this is a partial-line comment
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Partial-line comment. Note the semicolon, used as if the comment is
|
|
another command on that line.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim s as string
|
|
s="/data/docs/vb6_to_tcl.htm"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set s {/data/docs/vb6_to_tcl.htm}
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of a string quoted with braces. Most Tcl substitutions
|
|
are NOT done in a string quoted with braces. If the string contains
|
|
variables or other items that would be substituted, these will be
|
|
deferred, but may be substituted at a later time. This is often
|
|
done by commands that implement control structures, such as
|
|
'if' or 'while'. Once you start to get familiar
|
|
with Tcl initially, try to thoroughly understand this process
|
|
because it's important to getting 'good' in Tcl.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set s "/data/docs/vb6_to_tcl.htm"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of a quoted string. All Tcl substitutions (variables,
|
|
commands, backslashes) are available within a quoted string.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set s /data/docs/vb6_to_tcl.htm
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of an unquoted string. All Tcl substitutions (variables,
|
|
commands, backslashes) are available within an unquoted string. The
|
|
interpreter simply takes the string as the third word in the set
|
|
command (second argument to the set command). This works if there
|
|
is no whitespace or certain other characters in the string. Use
|
|
judiciously, especially when dealing with arbitrary data entered by
|
|
the user.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
dim s as string
|
|
s = vbCrLf &"Free software is not just" &vbCrLf _
|
|
&"about being 'free of charge'" &vbCrLf _
|
|
&"but about freedom to create" &vbCrLf _
|
|
&"and use the best possible tools." &vbCrLf
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set s {
|
|
Free software is not just
|
|
about being 'free of charge'
|
|
but about freedom to create
|
|
and use the best possible tools.
|
|
}
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of multi-line string. Note the more cluttered syntax in
|
|
VB, which makes it more difficult to read than the Tcl code.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim s as string
|
|
dim t as string
|
|
s = trim(t)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
set s [string trim $t]
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of function return value. The third word of this set
|
|
command is surrounded in square brackets. That means it is itself a
|
|
command to be executed, with the result taking its place as the
|
|
third word of the set command.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim s as string
|
|
dim t as string
|
|
s = lcase(trim(t))
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
set s [string tolower [string trim $t]]
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of function-of-function.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim x as double
|
|
dim y as double
|
|
x = (y + 10) * 5
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
set x [expr {($y + 10) * 5}]
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Assignment of result of a mathematical expression. The Tcl
|
|
interpreter relies on the expr command to evaluate mathematical or
|
|
logical expressions. Many other commands such as 'if' or
|
|
'while' also rely on expr in their implementation. When
|
|
used explicitly, expr should be passed a single argument which is a
|
|
string containing the expression (as shown here). That could get
|
|
cumbersome in simple cases where you just want to add a certain
|
|
increment to a variable. Try using the incr command for that
|
|
instead.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim s as string
|
|
s = s &"more text"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
append s {more text}
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Append to an existing string. This is one of the slowest operations
|
|
in VB, but is typically very speedy in Tcl. Speed is important here
|
|
because it is often done within loops or compound loops.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim s as string
|
|
dim t as string
|
|
dim u as string
|
|
s = "I'll ask " & t & " to email " & trim(u) & " with the price" </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
set s "I'll ask $t to email [string trim $u] with the price"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Building a string by substitution.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> print "hello"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
> Displays hello.
|
|
</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Print to console (VB actually prints to a form or to the debug
|
|
window).</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> sub my_sub (byval a as integer, byval b as string)
|
|
|
|
debug.print "I'll ask " & b
|
|
|
|
end sub
|
|
|
|
function my_function (byval a as integer, _
|
|
optional byval b as string = "Mark") _
|
|
as string
|
|
|
|
my_function = "I'll ask " & b
|
|
|
|
end function
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
proc my_sub {a b} {
|
|
|
|
puts "I'll ask $b"
|
|
|
|
}
|
|
|
|
proc my_function {a {b Mark}} {
|
|
|
|
return "I'll ask $b"
|
|
|
|
}
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Procedure definition. Note that VB uses a separate syntax for subs
|
|
and for functions. Tcl uses the <B
|
|
CLASS="COMMAND"
|
|
>proc</B
|
|
> command to define
|
|
either one. <B
|
|
CLASS="COMMAND"
|
|
>proc</B
|
|
> itself is an ordinary Tcl command that
|
|
executes like any other command. Its first argument is a Tcl list
|
|
of the parameters of the new procedure. Its second argument is a
|
|
large string containing the body of the new procedure (actual Tcl
|
|
script). <EM
|
|
>Important:</EM
|
|
> Tcl is case sensitive in
|
|
almost all operations, including all references to command names
|
|
and variable names, as well as (by default) string data
|
|
comparisons. So a call to <B
|
|
CLASS="COMMAND"
|
|
>Proc</B
|
|
> would cause an error
|
|
(capital P), as would a call to <TT
|
|
CLASS="VARNAME"
|
|
>My_Sub</TT
|
|
>, or a reference to
|
|
the variable <TT
|
|
CLASS="VARNAME"
|
|
>B</TT
|
|
> within <TT
|
|
CLASS="VARNAME"
|
|
>my_sub</TT
|
|
> (b was
|
|
defined as lower case).</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
|
|
dim i as integer
|
|
if i < 0 then i = 0 else i = i - 1
|
|
|
|
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>if {$i < 0} {set i 0} {incr i -1}
|
|
|
|
# alternate form
|
|
if {$i < 0} then {set i 0} else {incr i -1}
|
|
|
|
# another alternate form
|
|
if {$i < 0} then {
|
|
set i 0
|
|
} else {
|
|
incr i -1
|
|
} </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>'if' conditional execution. The Tcl 'if' command
|
|
ignores the optional keywords 'then' and 'else' if
|
|
they are present. Since both code blocks are just strings, they can
|
|
be enclosed in braces and nicely formatted as shown. To avoid
|
|
syntax errors, also enclose any non-trivial test expression in
|
|
braces. That way substitutions (such as $i here) are deferred until
|
|
the 'if' command passes the test expression to the
|
|
expression parser.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim i as integer
|
|
i = 1
|
|
while i < 2000
|
|
i = i * 2
|
|
wend
|
|
|
|
'alternate form
|
|
i = 1
|
|
do while i < 2000
|
|
i = i * 2
|
|
loop </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
|
|
set i 1
|
|
while {$i < 2000} {
|
|
set i [expr {$i * 2}]
|
|
}
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>'while' loop. This is similar to the Tcl 'if'
|
|
command in that it takes a test expression as its first argument,
|
|
followed by a string of code.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dim i as integer
|
|
for i = 0 to 8
|
|
'nine passes 0-8
|
|
debug.print i
|
|
next
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>for {set i 0} {$i < 9} {incr i} {
|
|
# nine passes 0-8
|
|
puts $i
|
|
}
|
|
|
|
# alternate form
|
|
for {set i 0} {$i <= 8} {incr i} {
|
|
# again, nine passes 0-8
|
|
puts $i
|
|
}
|
|
|
|
# another alternate form
|
|
for {set i 1} {$i <= 9} {incr i} {
|
|
# nine passes 1-9
|
|
puts $i
|
|
}
|
|
|
|
# yet another alternate form - less readable
|
|
set i 1
|
|
for {} {[incr i] <= 9} {} {
|
|
# nine passes 1-9
|
|
puts $i
|
|
} </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>'for' loop with an integer counter. In Tcl (or any other
|
|
language) this is equivalent to a 'while' loop. In some
|
|
languages such as VB, 'for' is not as flexible as
|
|
'while'. In Tcl this is not the case. Anything can be used
|
|
as the initialization code, the test-for-continuation expression,
|
|
and the increment code. Those pieces are not restricted to doing
|
|
anything in particular, as you can see by the final example.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim c as new collection
|
|
dim o as object
|
|
c.add "Mark"
|
|
c.add "Roy"
|
|
c.add "Brian"
|
|
for each o in c
|
|
debug.print o
|
|
next
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
|
|
set c [list Mark Roy Brian]
|
|
foreach o $c {
|
|
puts $o
|
|
}
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Loop through items in a data structure. In Tcl, a list data
|
|
structure is used. VB has no direct equivalent to that, but a
|
|
collection object is the most similar. Note that VB collections are
|
|
far slower than Tcl lists in typical operations due to the overhead
|
|
of using method calls to objects. Also note that there are
|
|
<EM
|
|
>far more powerful and creative uses</EM
|
|
> of the
|
|
foreach command that are not shown here. Those have no direct
|
|
equivalent in VB.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim s as string
|
|
select case s
|
|
case "John"
|
|
debug.print "Mellencamp"
|
|
case "Steve"
|
|
debug.print "Tyler"
|
|
case else
|
|
debug.print "Unknown"
|
|
end select
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
switch -exact $s {
|
|
John {puts Mellencamp}
|
|
Steve {puts Tyler}
|
|
default {puts Unknown}
|
|
}
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>One-of-many execution. Note the Tcl version is case sensitive. In
|
|
VB it often is not, depending on the 'option compare' that
|
|
is in effect for the module. The <TT
|
|
CLASS="OPTION"
|
|
>-exact</TT
|
|
> option specifies
|
|
an exact string match is required, as opposed to a pattern match or
|
|
regular expression match (this has no bearing on case sensitivity).
|
|
Also note that there are more powerful and creative uses of the
|
|
switch command that are not shown here.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
on error goto handler
|
|
debug.print a 'a is undeclared.
|
|
...
|
|
handler:
|
|
debug.print err.number, err.description
|
|
|
|
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> if [catch {
|
|
puts $a ;# a has not been set
|
|
} my_err] {
|
|
puts "error message: $my_err"
|
|
puts "stack trace: $errorInfo"
|
|
# these things would have been shown
|
|
# by the default error handler anyway.
|
|
} else {
|
|
puts {All is well.}
|
|
# the else block is optional.
|
|
}
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Error handling. In VB, handling errors concisely can be a problem,
|
|
especially if different actions need to be taken based on which
|
|
part of the code failed. Tcl <B
|
|
CLASS="COMMAND"
|
|
>catch</B
|
|
> command neatly solves
|
|
these problems. In addition, Tcl automatically provides a stack
|
|
trace of the code that failed. In VB, the stack trace has to be
|
|
explicitly built by the code, if a stack trace is desired while the
|
|
application is in production (not in the IDE). This is an advantage
|
|
for Tcl when debugging in the field. Note that <B
|
|
CLASS="COMMAND"
|
|
>catch</B
|
|
>
|
|
returns a boolean 1 or 0, which is typically used with
|
|
'if', as shown here.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set i [expr $e]
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Pass an arbitrary mathematical expression to the interpreter for
|
|
evaluation. This could be an expression entered by the user, or
|
|
composed by earlier code. This is one of the most powerful aspects
|
|
of Tcl. It is not available at all in VB.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set s [eval $c]
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Pass arbitrary code to the interpreter for execution. This could be
|
|
some script entered by the user, or composed by earlier code. This
|
|
is one of the most powerful aspects of Tcl. It is not available at
|
|
all in VB.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> source my_script.tcl
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Pass an arbitrary filename to the interpreter for execution of that
|
|
file as a script. This is one of the most powerful aspects of Tcl.
|
|
It is not available at all in VB.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set var_name marks_age
|
|
incr $var_name
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Perform operations on an arbitrarily-chosen variable. The code
|
|
shown here will increment the variable <TT
|
|
CLASS="VARNAME"
|
|
>marks_age</TT
|
|
>.
|
|
Its name (the string "marks_age") is stored in the variable
|
|
<TT
|
|
CLASS="VARNAME"
|
|
>var_name</TT
|
|
>. In fact, all parts of every command are subject
|
|
to one pass of substitution by the interpreter just prior to execution. So any
|
|
part of any command (even the name of the command itself) can be
|
|
varied based on data or any other criteria. This is one of the most
|
|
powerful aspects of Tcl. It is not available at all in VB.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim s as string
|
|
dim li as string
|
|
dim f_num as integer
|
|
s = ""
|
|
f_num = freefile
|
|
open "my_file.txt" for input as #f_num
|
|
while not eof(f_num)
|
|
line input #f_num, li
|
|
s = s & li & vbCrLf
|
|
wend
|
|
close #f_num
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
|
|
|
|
set f [open my_file.txt r]
|
|
set s [read $f]
|
|
close $f
|
|
|
|
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Read whole file into a variable. This VB code is very slow for even
|
|
moderately large files. And it has no way to deal with newline
|
|
characters in the data. The Tcl code accepts and preserves newlines
|
|
in the data. It also normalizes different newline characters into a
|
|
single kind of standardized newline character (by default). This
|
|
code applies equally well to raw data, or Tcl lists, or Tcl arrays.
|
|
The <TT
|
|
CLASS="OPTION"
|
|
>r</TT
|
|
> in the <B
|
|
CLASS="COMMAND"
|
|
>open</B
|
|
> command indicates
|
|
'read' mode.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> dim a(1 to 3) as string
|
|
a(1) = "Mark"
|
|
a(2) = "Brian"
|
|
a(3) = "Roy"
|
|
'oops - need more elements
|
|
redim preserve a(1 to 10) as string
|
|
a(4) = "John"
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> array set a [list 1 Mark 2 Brian 3 Roy]
|
|
set a(4) John
|
|
# now some different kinds of
|
|
# element names in the same array
|
|
set a(Red) Hat
|
|
set a(Linux,RedHat) 7.1
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Array vs. Array. VB arrays are restricted to using numbers as
|
|
subscripts (subscripts, or indexes, are called 'element
|
|
names' in Tcl). And the array must be declared to be a certain
|
|
size - expanding it requires a (slow) 'ReDim Preserve'
|
|
operation. Tcl arrays automatically expand, and they use a
|
|
super-efficient hash table implementation to handle even hundreds
|
|
of thousands of elements with superior speed. Tcl uses any kind of
|
|
data for an element name, and different styles can even be mixed
|
|
within the same array. There are no restrictions on the number of
|
|
dimensions in each element. Tcl provides simple ways to iterate
|
|
through the array, or through only certain elements in the array
|
|
(by filter). You can also obtain a full or partial list of the
|
|
element names, and do other operations more conveniently than in
|
|
VB. To get just a portion of those capabilities in VB requires the
|
|
use of a collection or dictionary object. Each of those comes with
|
|
its own quirks and pitfalls, such as even higher overhead than a VB
|
|
array.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> array set my_array $my_list
|
|
set my_list [array get my_array]
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>List to array, and back. Easy and rapid translation between these
|
|
two primary data structures means that the tools for each one can
|
|
be applied to both. They multiply each other's usefulness.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>dim a(1 to 100) as string
|
|
dim i as integer
|
|
dim f_num as integer
|
|
f_num = freefile
|
|
open "my_file.txt" for output as #f_num
|
|
for i=1 to 100
|
|
print #f_num, a(i)
|
|
next
|
|
close #f_num </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
set f [open my_file.txt w]
|
|
puts $f [array get a]
|
|
close $f
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Write whole array. In this VB code, and frequently in other VB
|
|
code, newlines and possibly other characters appearing in the data
|
|
will cause errors during a later step (the read-back). This becomes
|
|
a problem whenever your code deals with arbitrary data entered by
|
|
the user. In Tcl they do not - the data is kept "clean"
|
|
at all times. In addition, various combinations of carriage return
|
|
(0x0D or decimal 13) and line-feed (0x0A or decimal 10) characters
|
|
are automatically normalized by default. Note that these two examples
|
|
don't produce identical output files. The Tcl example, like the
|
|
VB, writes a plain text file. But the Tcl file will be read back in
|
|
(by Tcl) and automatically have the same number of elements, same
|
|
element names, etc.. The Tcl list data structure is used for this.
|
|
Using it ensures that the data is formatted in a concise,
|
|
non-ambiguous, textual representation. It is also readable and
|
|
writable by humans.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
(No equivalent)
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set f [open my_file.txt w]
|
|
puts $f [array get a red*]
|
|
close $f
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Write certain elements of an array. In the VB, a collection or
|
|
dictionary object would have to be used for this. A loop would
|
|
iterate through all the elements and select them as appropriate. In
|
|
the Tcl, the array's name is <TT
|
|
CLASS="LITERAL"
|
|
>a</TT
|
|
> and a string pattern
|
|
of <TT
|
|
CLASS="LITERAL"
|
|
>red*</TT
|
|
> (case sensitive) is used as a filter to select
|
|
elements at high speed.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set my_list [lsort $my_list]
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Sort a list. The sort can be reversed, or ordered by numeric value,
|
|
etc. It can also order a list of sublists using an index element.
|
|
Tcl contains a full suite of commands for manipulating the list
|
|
data structure. See also <B
|
|
CLASS="COMMAND"
|
|
>lappend</B
|
|
>,
|
|
<B
|
|
CLASS="COMMAND"
|
|
>linsert</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>lreplace</B
|
|
>,
|
|
<B
|
|
CLASS="COMMAND"
|
|
>lsearch</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>concat</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>split</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>join</B
|
|
>, etc. Tcl lists can also be nested arbitrarily,
|
|
and the <B
|
|
CLASS="COMMAND"
|
|
>foreach</B
|
|
> command has no trouble dealing with that.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>' requires a reference to ADO
|
|
' assume we have a connection called conn
|
|
dim rs as new recordset
|
|
rs.open "select id, name, age from people", _
|
|
my_connection, adOpenStatic
|
|
' processing code goes here
|
|
rs.close
|
|
set rs=nothing </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
package require tclodbc
|
|
# assume we have a connection called conn
|
|
conn read a "select id, name, age from people"
|
|
# processing code goes here
|
|
unset a ;# get rid of this array
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Retrieve a simple array of data from a database table. In VB data
|
|
is always retrieved in a recordset object. In Tcl it can be read
|
|
into an array and/or a list, depending on your needs, and the
|
|
database package in use.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
(No equivalent)
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>package require http
|
|
set httpTrans [http::geturl $pageURL]
|
|
upvar #0 $httpTrans state
|
|
if {$state(status) == {ok}} {
|
|
puts $state(body)
|
|
} </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Retrieve a document or file from a web server.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> (No equivalent)
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> regexp -all {src=['"](.+?)['"]} $body my_images
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Complex string pattern search and extraction. Tcl uses
|
|
<EM
|
|
>regular expressions</EM
|
|
> for this.
|
|
<EM
|
|
>Regular expression</EM
|
|
> is a specification for a
|
|
string pattern to be matched, similar in concept to the
|
|
wildcard patterns used with VB's 'like' operator,
|
|
except on steroids - a <EM
|
|
>whole lot</EM
|
|
> of steroids.
|
|
Regular expressions are several times more powerful and flexible
|
|
than 'like' patterns. For an informal introduction to
|
|
regular expressions, see <A
|
|
HREF="http://zez.org/article/articleprint/11"
|
|
TARGET="_top"
|
|
>http://zez.org/article/articleprint/11</A
|
|
>.
|
|
Tcl's regular expression parser is written in hand-optimized
|
|
C code and is available to Tcl in several different commands
|
|
(<B
|
|
CLASS="COMMAND"
|
|
>regexp</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>regsub</B
|
|
>,
|
|
<B
|
|
CLASS="COMMAND"
|
|
>lsearch</B
|
|
>, etc). The simpler, less powerful versions
|
|
you're used to are also available for use in several different
|
|
commands (<B
|
|
CLASS="COMMAND"
|
|
>glob</B
|
|
>, <B
|
|
CLASS="COMMAND"
|
|
>string match</B
|
|
>,
|
|
<B
|
|
CLASS="COMMAND"
|
|
>lsearch</B
|
|
>, and so on). This example
|
|
would take 15 to 50 lines of VB code, depending on how robust and
|
|
how tolerant of different situations it needs to be. In addition,
|
|
that is some of the most difficult, error-prone, and slowest code
|
|
that can be written in VB (voice of experience). Here, the code
|
|
quickly obtains a list of the URLs of every image on an HTML page.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
(No equivalent)
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set find {<tr>(.*?)<td>(.*?)</td><td>(.*?)</td><td>(.*?)</td>(.*?)</tr>}
|
|
set replace {<tr>\1<td width=20%>\2</td><td width=40%>\3</td><td width=30%>\4</td>\5</tr>}
|
|
regsub -all -nocase $exp $body $replace result
|
|
puts $result </PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Complex string pattern search and substitution. Again, Tcl uses
|
|
regular expressions. This example would take 40 lines of VB code or
|
|
more, especially if it is logically organized with sufficient
|
|
comments for a maintenance programmer to follow it. And again, it
|
|
is some of the most difficult, error-prone, and slowest code that
|
|
can be written in VB. Here the set of three cells in
|
|
<EM
|
|
>every row in the HTML body</EM
|
|
> is altered
|
|
systematically, while the contents of each cell is preserved.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
(No equivalent)
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> set handle [socket markhpc.dcisite.com 2000]
|
|
set greeting [read $handle]
|
|
close $handle
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Make a connection to a network socket (act as a client) and
|
|
retrieve data. The example assumes a server is listening on TCP
|
|
port 2000 of the specified host.</TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
>
|
|
|
|
(No equivalent)
|
|
|
|
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
><TD
|
|
WIDTH="50%"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
><P
|
|
><TABLE
|
|
BORDER="0"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="PROGRAMLISTING"
|
|
> proc greeting {handle client_ip client_port} {
|
|
puts $handle {Welcome to our greeting server!}
|
|
close $handle
|
|
}
|
|
socket -server greeting 2000
|
|
</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
COLSPAN="2"
|
|
ALIGN="LEFT"
|
|
VALIGN="TOP"
|
|
>Implement a network server to answer the client shown above. This
|
|
is the complete script. If you're using Wish (the Tcl windowing
|
|
shell) this will run all day as shown. If you're using Tclsh
|
|
(the console Tcl shell) add a <B
|
|
CLASS="COMMAND"
|
|
>vwait</B
|
|
> command at the end,
|
|
to make the program wait for events instead of terminating at the
|
|
end of the script. That difference between the two shells is
|
|
necessary and intentional, since Wish is event-driven by default,
|
|
and Tclsh is not.</TD
|
|
></TR
|
|
></TBODY
|
|
></TABLE
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="NAVFOOTER"
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"><TABLE
|
|
SUMMARY="Footer navigation table"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
CELLPADDING="0"
|
|
CELLSPACING="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="left"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="intro.html"
|
|
ACCESSKEY="P"
|
|
>Prev</A
|
|
></TD
|
|
><TD
|
|
WIDTH="34%"
|
|
ALIGN="center"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="index.html"
|
|
ACCESSKEY="H"
|
|
>Home</A
|
|
></TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="more.html"
|
|
ACCESSKEY="N"
|
|
>Next</A
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="left"
|
|
VALIGN="top"
|
|
>Introduction</TD
|
|
><TD
|
|
WIDTH="34%"
|
|
ALIGN="center"
|
|
VALIGN="top"
|
|
> </TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
>Getting More Information</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |