:TITLE: Assigning values to variables 
;#
;# RCSID: $Header: /home/clif/CVS_ROOT/TclTutor/Tcl2.lsn,v 1.13 2000/04/24 16:17:51 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# See file "NOTICE" for licensing terms.
;#
:LESSON_TEXT_START_LEVEL 0:
<CODE>Set</CODE> is the assignment operator in Tcl.
<P>
Tcl stores data as strings, and only converts to numbers when necessary.
<P>
When referring to a variable by value, the name is preceded by a <B>$</B>.
When referring to the variable by reference, the $ is left off.
<P>
The argument to the <CODE>set</CODE> command must be passed by reference,
so it is called with simply a variable name, and no $. 
<P>
The <CODE>puts</CODE> command accepts data passed by value, so you call
<CODE>puts</CODE> with a $ preceding the variable name. 
<DL>
<B><DT>set</B> <I>varName ?value?</I>
<DD>If <I>value</I> is
specified, then the contents of the variable <I>varName</I> are set equal 
to <I>value</I>.  
<P>
If <I>varName</I> consists only of alphanumeric characters, and no 
parenthese, it is a scalar variable.
<P>
If <I>varName</I> has the form <I>varName(index)</I>, it is a member of an associative array.  
<P>
<B>Set</B> returns the value of variable <I>varName</I>.
</DL>
:TEXT_END:
<P>
:LESSON_TEXT_START_LEVEL 1:
Tcl stores data as strings, and only converts to numbers when necessary for
calculations or comparisons.
<P>
The assignment operator in Tcl is <CODE>set</CODE>.
<P>
When <B>set</B> is called with two arguments, as in:<PRE><CODE>
set fruit "Cauliflower";
</CODE></PRE>
it places the second argument (<I>"Cauliflower"</I>) in the memory space
referenced by the first argument
(<I>fruit</I>). <B>Set</B> always
returns the contents of the variable named in the first argument.  Thus, 
when
<B>set</B> is called with two arguments, it places the second argument in
the memory space referenced by the first argument and then returns
the second argument.
<P>
The first argument to a <B>set</B> command can be either a single word,
like <B>fruit</B> or <B>pi</B>, or it can be a member of an array.  Arrays
will be discussed in greater detail later, for the time being just remember
that many data can be collected under a single variable name, and an individual
datum can be accessed by its index within that array.  Indexing into an
array in Tcl is handled by putting the index within parentheses after the
name of the variable.
<P>
<B>Set</B> can also be invoked with only one argument.  When called with just
one argument, it will return the contents of that argument. 
<P>
Here's a summary of the <B>set</B> command.  Examine it, then
click on the <B>Run Example</B> button, and study the output while you 
continue reading this text.
<DL>
<B><DT>set</B> <I>varName ?value?</I>
<DD>If <I>value</I> is
specified, then the contents of the variable <I>varName</I> are set equal 
to <I>value</I>.  
<P>
If <I>varName</I> consists only of alphanumeric characters, and no 
parenthese, it is a scalar variable.
<P>
If <I>varName</I> has the form <I>varName(index)</I>, it is a member of an associative array.  
<P>
<B>Set</B> returns the value of the variable <I>varName</I>.
</DL>
<P>
If you look at the example code, you'll notice that in the
<CODE>set</CODE> command the first argument is typed with only its
name, but in the <CODE>puts</CODE> statement the argument is preceeded with
a <B>$</B>. 
<P>
This is because Tcl passes data to subroutines either by reference or by
value.  Commands that don't change the contents of a variable usually have
their arguments passed by value.  Commands that <B>DO</B> change the value of
the data must have the data passed by reference.
<P>
Again, modify the example scripts a little, and then click on to the 
next lesson.
:TEXT_END:
<P>
:LESSON_TEXT_START_LEVEL 2:
In order to make a programming language useful, you need to have a way
to store and access data in the program.  To do this, you allocate space
in the computer's memory and put the data you wish to work with in that
space.  The data can be anything from the mass of a neutron to the poem
about the Jabberwock.  The important thing is that it is placed in computer
memory, and that there is a way to get at it when you want to.
<P>
In Tcl space is reserved for you whenever you put data into a new variable,
and you access the data	you put in that space by that variable
name.
<P>
To create a variable and put some data into it, we use the
<CODE>set</CODE> command. 
<P>
When <B>set</B> is called with two arguments, as in:<PRE><CODE>
set fruit "Cauliflower";
</CODE></PRE>
it places the second argument (<I>"Cauliflower"</I>) in the memory space
referenced by the first argument
(<I>fruit</I>). <B>Set</B> always
returns the contents of the variable named in the first argument.  Thus, 
when
<B>set</B> is called with two arguments, it places the second argument in
the memory space referenced by the first argument and then returns
the second argument.
<P>
The first argument to a <B>set</B> command can be either a single word,
like <B>fruit</B> or <B>pi</B>, or it can be a member of an array.  Arrays
will be discussed in greater detail later, for the time being just remember
that many data can be collected under a single variable name, and an individual
datum can be accessed by its index within that array.  Indexing into an
array in Tcl is handled by putting the index within parentheses after the
name of the variable.
<P>
<B>Set</B> can also be invoked with only one argument.  When called with just
one argument, it will return the contents of that argument. 
<P>
Here is an extract from the man page to summarize the way <B>set</B>
behaves.
<DL>
<B><DT>set</B> <I>varName ?value?</I>
<DD>If <I>value</I> is
specified, then the contents of the variable <I>varName</I> are set equal 
to <I>value</I>.  
<P>
If <I>varName</I> consists only of alphanumeric characters, and no 
parenthese, it is a scalar variable.
<P>
If <I>varName</I> has the form <I>varName(index)</I>, it is a member of an associative array.  
<P>
<B>Set</B> returns the value of the variable <I>varName</I>.
</DL>
<P>
Click on the <B>Run Example</B> button, and study the output while you 
continue reading this text.
<P>
If you look at the example code, you'll notice that in the
<CODE>set</CODE> command the first argument is typed with only its
name, while in the <CODE>puts</CODE> statement the argument is preceeded with
a <B>$</B>. 
<P>
Sometimes when you pass the contents of a variable to a subroutine, you
want to allow the subroutine to modify the data if it needs to, but
not affect the main copy.  In this case, you put a $ in front of the
variable when you call the subroutine.  Doing this reserves a new space
in memory and makes a copy of the contents of variable_name.  The subroutine
is called with this copy of the data, and can do whatever is necessary as
it processes the data.  When it is done, the original copy of the data is
still intact.  This is called "Pass by Value", since the value of the
variable is passed to the subroutine.
<P>
Other times (such as the <CODE>set</CODE> command), you want the
contents of the variable changed.  In this case, you want to pass a
reference to the location in memory where that variable's data is
stored, so that the command can modify that data in place.  In Tcl this
is done by *NOT* putting a $ in front of the variable name.  This is
called "Pass by Reference", since a reference to the location is
passed to the command. 
<P>
So, with the <CODE>set</CODE> command you simply use the variable name,
so that the reference is passed to <CODE>set</CODE>.  <CODE>Set</CODE>
places the data in the second argument in the location referenced by the
first argument. 
<P>
However, with the <CODE>puts</CODE> command, we don't want any chance of
our original data being changed, so we call <CODE>puts</CODE> by value,
and give it a fresh copy of the data to output. 
<P>
Again, modify the example scripts a little, and then click on to the 
next lesson.
:TEXT_END:
<P>
:CODE_START:
;# Assign a string to variable X
set X "This is a string"

;# Assign a number to variable Y
set Y 1.24

;# Display the contents  of X and Y
puts $X
puts $Y

;# Just puts a divider
puts "..............................."

;# More than one item can be put in a single puts
set label "The value in Y is: "
puts "$label $Y"
:TEXT_END:
<P>

