code so far is as follows:
###########
#PROCEDURES
#######################################################################################
# Display prompt; push the partial line of text to the console
proc yes_no {userlib} {
puts "Do you want $userlib Libraries (enter Y/N)? "
# Loop until we have satisfactory input
set noinput 1
while {$noinput} {
# Read user input into a variable
gets stdin user_line
# Check user input - only the first character
switch -- [string index $user_line 0] {
Y {
set noinput 0
set yes 1
}
N {
set noinput 0
set yes 0
}
default {
puts -nonewline "Try again: $userlib Libs (Y/N)? "
flush stdout
}
}
}
# concatenate library name with yes/no response
return $userlib_yes
}
#######################################################################################
yes_no {fred}
# help debug
puts "pause 0"
gets stdin user
if {$fred_yes == 1} {
puts "you typed yes to fred libraries"
} else {
puts "you entered no to Fred libraries" }
# help debug
puts "pause 1"
gets stdin user
yes_no {george}
if {$george_yes == 1} {
puts "You typed yes to Geoerge libraries"
} else {
puts "you entered no to Geoerge libraries" }
# help debug
puts "pause 2"
gets stdin user
set fred_yes [yes_no fred]
(The variable "userlib_yes" you set in [yes_no] is a _local_ variable.
Its value is passed up to the calling proc/code, but not its name.)
You _can_ do what you wanted to, but I advise you against this:
it makes your program much more complicated and difficult
to maintain than you might think!
Regards,
Arjen
The above is looking for a varaible named 'userlib_yes' and failing
because you haven't created a variable named 'userlib_yes'.
To solve the immediate problem, what you want is something like this
(note the use of {} to separate the variable name usrlib from the rest
of the string)
return ${userlib}_yes
HOWEVER, that doesn't do what you want. If userlib is 'fred', it will
return the string 'fred_yes'. It appears that later in your script you
expect a global variable named 'fred_yes' to contain the value 1 or 0.
I don't recommend it, but if you really want your proc to create a
variable as a side effect (or as the main effect...) you would do it
like this:
set ::${userlib}_yes $yes
That creates a global varible named, in the above example, 'fred_yes',
and sets its value to whatever is stored in 'yes'.
> #######################################################################################
> yes_no {fred}
>
> # help debug
> puts "pause 0"
> gets stdin user
>
> if {$fred_yes == 1} {
I think a much cleaner, easier-to-maintain way of doing that is to do it
this way:
set fred_yes [yes_no fred]
if {$fred_yes == 1} ...
The problem with your original scheme is that it is not at all obvious
where the variable fred_yes gets created. With the above solution it
becomes totally obvious.
I wish I could stick to VHDL, I understand that quite well.
You might want to accept lower case as well:
proc yes_no {userlib} {
puts -nonewline "Do you want $userlib Libraries (enter Y/N)? "
flush stdout
while {1} { #loop forever until told to stop
gets stdin line
set ans [string tolower [string index $line 0]]
if {$ans == "y"} {
set yes 1
break ;# get out of while loop
} elseif {$ans == "n"} {
set yes 0
break ;# get out of while loop
} else {
puts -nonewline "Try again: $userlib Libs (Y/N)? "
flush stdout
}
}
return $yes
}
Note also that "y" and "n" are valid boolean values in Tcl. So you can
be more forgiving in accepting input -- let the user enter "yes", "Y",
"no", 1, 0, etc:
proc yes_no {userlib} {
puts -nonewline "Do you want $userlib Libraries (yes|no)? "
flush stdout
while {1} {
gets stdin line
if {[string is boolean $line]} {
set answer $line
break
} else {
puts -nonewline "Try again: $userlib Libs (enter Y or N)? "
flush stdout
}
}
return $answer
}
Now, the return value from yes_no is a valid Tcl boolean that can be
used directly as an [if] condition, so this will work:
foreach user {fred jim sue} {
if {[yes_no $user]} {
puts "you want to use ${user}'s libraries"
} else {
puts "poor unwanted $user"
}
}
--
Glenn Jackman
NCF Sysadmin
gle...@ncf.ca
The reason I ask: I am considering offerig a Tcl course to a company
here, but I have some problems structuring it like:
Tcl intro: 3 days (2 days? 4?) and what to cover in these days
Tk intro: another x days (2? 3?)
This is going to be followed by (optional) Tcl specials like
- event loop
- handling XML
- ...
Any information or idea will be greatly appreciated.
Best regards
Helmut Giese
> The reason I ask: I am considering offerig a Tcl course to a company
> here, but I have some problems structuring it like:
> Tcl intro: 3 days (2 days? 4?) and what to cover in these days
> Tk intro: another x days (2? 3?)
>
Not having actually tried it, I personally think a "Tcl Intro" can be
done in a single day. The trick isn't to intro tcl by saying "here's the
if statement, here's the foreach statement, here's a global variable,
this is a string, this is a list, ...". I think the right way is to talk
about the concept of tcl -- commands that take arguments based on word
boundaries, and return results. Talk about quoting and lists versus
strings and the meaning of [ ... ]. Maybe even (*gasp*) explain eval
and/or {expand}. Mention the difference between 'set foo bar' and 'set
$foo bar'.
All of that can be covered in a single day, no? The point is, if they
know how tcl parses a line of code and invokes a command, they can
easily learn all of the tcl commands from the man pages. The big hurdle
in learning tcl is not in learning the tcl way of doing a loop versus
some other language but rather learning "the tcl way" in general.
Day two, then, would be a survey of the most common tcl commands such as
if, foreach, while, set, proc, etc. though proc could be covered on day
1 to show how a user-created procedure acts just like a built-in command.
> This is going to be followed by (optional) Tcl specials like
> - event loop
If you're going to teach tk, I'd recommend you teach the event loop
first. Understanding how the event loop works is important to understand
how bindings work.
I think the basics of tk, including the event loop, can be covered in
two days if you're working with programmers who already understand the
concept of a loop.
Hi Bryan,
>Not having actually tried it, I personally think a "Tcl Intro" can be
>done in a single day.
<shudder> hope the prospective customer isn't reading this, want to
earn some money ...
> The trick isn't to intro tcl by saying "here's the
>if statement, here's the foreach statement, here's a global variable,
>this is a string, this is a list, ...". I think the right way is to talk
>about the concept of tcl -- commands that take arguments based on word
>boundaries, and return results. Talk about quoting and lists versus
>strings and the meaning of [ ... ].
Yes, this is the base of my "concept" (can't really call it like this
yet), too: these are the real basics of understanding Tcl.
> Maybe even (*gasp*) explain eval
>and/or {expand}. Mention the difference between 'set foo bar' and 'set
>$foo bar'.
... or how to get at an element of an array given the array name in
one variable and the name of the key in another :)
>All of that can be covered in a single day, no? The point is, if they
>know how tcl parses a line of code and invokes a command, they can
>easily learn all of the tcl commands from the man pages.
Well, of course, but my point is of course that people will get a much
faster start if they are "taken by the hand" and led thru all the
major Tcl commands, lerning a trick or two along the road.
> The big hurdle
>in learning tcl is not in learning the tcl way of doing a loop versus
>some other language but rather learning "the tcl way" in general.
Reminds me of a thread of just a couple of days ago where someone
absolutely wanted to pass references to a proc in order to receive the
return values - because in C it is done this way (if you have more
than one value to return) and the aim was to please C programmers.
[snip]
>If you're going to teach tk, I'd recommend you teach the event loop
>first. Understanding how the event loop works is important to understand
>how bindings work.
Bryan, only a GUI expert like you could propose something like this :)
No, I think I'll start this part by /designing/ something: How to get
a nice looking GUI composed of some standard widgets using e.g.
'pack', the concepts behind 'pack', etc.
Then, yes, bindings will have to covered, and the event loop, and and
and ...
Hm, not being that much of a GUI guy this (teaching Tk) is an aspect I
am not exactly looking forward to - but I guess I can get the basics
across.
Bryan, thanks a lot for your input and best regards
Helmut Giese
IIRC, Ken Jones does an intro to Tcl in a day (or was it two days? I was
in a metakit tutorial at the time so I wasn't following closely) that
goes up to the level of writing small network servers. But he doesn't
include Tk in that. You can probably spin that out more if you include
plenty of hands-on time and a few exercises.
Donal.