proc nothing {} {
set aaa "Hallo"
button .b -text "Press me" -command {puts $aaa}
pack .b
}
When I'm pressing the button, I'm getting an error:
can't read "aaa": no such variable
The problem vanishes, when I change aaa to ::aaa (and, of course {puts $aaa}
to {puts $::aaa}), making it global. There isn't any remark at "button"
manual page, that variables, used as parameters for "command", must be globals.
What's wrong?
--
ZB
You may (and probably should) create your GUI inside a proc, but the
GUI itself operates in global scope. It sits around waiting for
events, and when they occur, it fires the appropriate script--also in
global scope. If the appropriate script is {puts $aaa}, then $aaa had
better exist in global scope (the scope in which the script was
called); otherwise, there will be an error.
The most common issues with bindings and variables arise out of
confusion over when substitution will occur. The textbook answer is
to use [list] or double quotes if you want substitution to occur when
the binding is created (or the -command is configured) and curly
braces if you want substitution to occur when the binding fires.
However, if you have complex binding scripts things can get pretty
messy and it can be hard to keep straight what's going to be
substituted when. Bryan Oakley has some excellent advice on keeping
your bindings and -commands clean: http://www.tclscripting.com/articles/apr06/article3.html
Hope that helps,
Aric
> If the appropriate script is {puts $aaa}, then $aaa had
> better exist in global scope (the scope in which the script was
> called); otherwise, there will be an error.
Yes, quite right - I realize, that example procedure had little sense, it
was just a poor illustration for the problem...
> [..] use [list] or double quotes if you want substitution to occur when
^^^^^^^^^^^^^^^^^^^^^^^^^^^
> the binding is created (or the -command is configured) and curly
^^^^^
> braces if you want substitution to occur when the binding fires.
^^^^^^
...which origin was, that I totally missed the difference. Thanks.
--
ZB
> To understand how -commands (and [bind]ings to Tk events) work, you
> need a basic understanding of how the event loop works.
>
> You may (and probably should) create your GUI inside a proc, but the
> GUI itself operates in global scope. It sits around waiting for
> events, and when they occur, it fires the appropriate script--also in
> global scope. If the appropriate script is {puts $aaa}, then $aaa had
> better exist in global scope (the scope in which the script was
> called); otherwise, there will be an error.
...
There is another important aspect to distinguish between braces and
lists, the time of evaluation - try this to see the difference:
set aaa "You pressed B"
set ba [button .ba -text "Press A" -command { puts $::aaa}]
set bb [button .bb -text "Press B" -command [list puts $::aaa]]
eval pack [winfo children .] -side left
set aaa "You pressed A"
--
Gerhard Reithofer
Tech-EDV Support Forum - http://support.tech-edv.co.at
> There is another important aspect to distinguish between braces and
> lists, the time of evaluation - try this to see the difference:
Yes, it's exactly Aric was talking about. I agree, it's very important - I
missed that, and because of this was my confusion.
--
ZB