Tcl/Tk: scope of variables for a function within a function
up vote
0
down vote
favorite
I'm getting lost on scoping variables in Tcl. I've got two procs I've written and stored in a file that I want to call in another script I'm writing. In my sourced file (which I'll call bar.tcl), I'm using upvar to define a bunch of variables at the beginning of my file that I plan to call within the procs I've defined within bar.tcl, which I'll call bar1 and bar2
I want to call the functions within bar.tcl from my code within foo.tcl. My functions work fine if I'm just interacting with bar.tcl in tclsh, but as soon as I call bar1 or bar2 from within a function in foo.tcl, I get an error can't read "alpha": no such variable
It seems I'm using upvar incorrectlys. Is this even the right tool for the job? What can I do so that I can achieve the following?
- define a bunch of variables at the beginning of
bar.tclthat I want to use in both procsbar1andbar2,and - call
bar1andbar2from within procs defined infoo.tcl
Here's my code in foo.tcl:
# foo.tcl
source bar.tcl
proc foo {fooValues} {
foreach fooValue $fooValues {
set myNewValue [bar1 $fooValue]
return $myNewValue
}
}
set myOldValues {5 10 15 20 25}
foo myOldValues
And here's my code in bar.tcl:
set a apples
set b bananas
set c cherries
set d dates
proc bar1 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$bar $alpha $bravo $charlie $delta"
return $myReturnValue
}
proc bar2 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$alpha $bravo $charlie $delta $bar"
return $myReturnValue
}
scope tcl upvar
add a comment |
up vote
0
down vote
favorite
I'm getting lost on scoping variables in Tcl. I've got two procs I've written and stored in a file that I want to call in another script I'm writing. In my sourced file (which I'll call bar.tcl), I'm using upvar to define a bunch of variables at the beginning of my file that I plan to call within the procs I've defined within bar.tcl, which I'll call bar1 and bar2
I want to call the functions within bar.tcl from my code within foo.tcl. My functions work fine if I'm just interacting with bar.tcl in tclsh, but as soon as I call bar1 or bar2 from within a function in foo.tcl, I get an error can't read "alpha": no such variable
It seems I'm using upvar incorrectlys. Is this even the right tool for the job? What can I do so that I can achieve the following?
- define a bunch of variables at the beginning of
bar.tclthat I want to use in both procsbar1andbar2,and - call
bar1andbar2from within procs defined infoo.tcl
Here's my code in foo.tcl:
# foo.tcl
source bar.tcl
proc foo {fooValues} {
foreach fooValue $fooValues {
set myNewValue [bar1 $fooValue]
return $myNewValue
}
}
set myOldValues {5 10 15 20 25}
foo myOldValues
And here's my code in bar.tcl:
set a apples
set b bananas
set c cherries
set d dates
proc bar1 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$bar $alpha $bravo $charlie $delta"
return $myReturnValue
}
proc bar2 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$alpha $bravo $charlie $delta $bar"
return $myReturnValue
}
scope tcl upvar
1
Yourreturnlines throughoutfoo.tclandbar.tclshould provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValueinstead ofmyReturnValueetc.
– mrcalvin
Nov 11 at 0:03
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm getting lost on scoping variables in Tcl. I've got two procs I've written and stored in a file that I want to call in another script I'm writing. In my sourced file (which I'll call bar.tcl), I'm using upvar to define a bunch of variables at the beginning of my file that I plan to call within the procs I've defined within bar.tcl, which I'll call bar1 and bar2
I want to call the functions within bar.tcl from my code within foo.tcl. My functions work fine if I'm just interacting with bar.tcl in tclsh, but as soon as I call bar1 or bar2 from within a function in foo.tcl, I get an error can't read "alpha": no such variable
It seems I'm using upvar incorrectlys. Is this even the right tool for the job? What can I do so that I can achieve the following?
- define a bunch of variables at the beginning of
bar.tclthat I want to use in both procsbar1andbar2,and - call
bar1andbar2from within procs defined infoo.tcl
Here's my code in foo.tcl:
# foo.tcl
source bar.tcl
proc foo {fooValues} {
foreach fooValue $fooValues {
set myNewValue [bar1 $fooValue]
return $myNewValue
}
}
set myOldValues {5 10 15 20 25}
foo myOldValues
And here's my code in bar.tcl:
set a apples
set b bananas
set c cherries
set d dates
proc bar1 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$bar $alpha $bravo $charlie $delta"
return $myReturnValue
}
proc bar2 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$alpha $bravo $charlie $delta $bar"
return $myReturnValue
}
scope tcl upvar
I'm getting lost on scoping variables in Tcl. I've got two procs I've written and stored in a file that I want to call in another script I'm writing. In my sourced file (which I'll call bar.tcl), I'm using upvar to define a bunch of variables at the beginning of my file that I plan to call within the procs I've defined within bar.tcl, which I'll call bar1 and bar2
I want to call the functions within bar.tcl from my code within foo.tcl. My functions work fine if I'm just interacting with bar.tcl in tclsh, but as soon as I call bar1 or bar2 from within a function in foo.tcl, I get an error can't read "alpha": no such variable
It seems I'm using upvar incorrectlys. Is this even the right tool for the job? What can I do so that I can achieve the following?
- define a bunch of variables at the beginning of
bar.tclthat I want to use in both procsbar1andbar2,and - call
bar1andbar2from within procs defined infoo.tcl
Here's my code in foo.tcl:
# foo.tcl
source bar.tcl
proc foo {fooValues} {
foreach fooValue $fooValues {
set myNewValue [bar1 $fooValue]
return $myNewValue
}
}
set myOldValues {5 10 15 20 25}
foo myOldValues
And here's my code in bar.tcl:
set a apples
set b bananas
set c cherries
set d dates
proc bar1 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$bar $alpha $bravo $charlie $delta"
return $myReturnValue
}
proc bar2 {bar} {
upvar a alpha
upvar b bravo
upvar c charlie
upvar d delta
set myReturnValue "$alpha $bravo $charlie $delta $bar"
return $myReturnValue
}
scope tcl upvar
scope tcl upvar
edited Nov 11 at 16:23
asked Nov 10 at 22:03
the_meter413
1337
1337
1
Yourreturnlines throughoutfoo.tclandbar.tclshould provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValueinstead ofmyReturnValueetc.
– mrcalvin
Nov 11 at 0:03
add a comment |
1
Yourreturnlines throughoutfoo.tclandbar.tclshould provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValueinstead ofmyReturnValueetc.
– mrcalvin
Nov 11 at 0:03
1
1
Your
return lines throughout foo.tcl and bar.tcl should provide for variable substitution. Right now, they return literally the variable names. Write $myReturnValue instead of myReturnValue etc.– mrcalvin
Nov 11 at 0:03
Your
return lines throughout foo.tcl and bar.tcl should provide for variable substitution. Right now, they return literally the variable names. Write $myReturnValue instead of myReturnValue etc.– mrcalvin
Nov 11 at 0:03
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.
Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:
upvar "#0" a alpha
This is equivalent to using global a modulo a variable alias (alpha).
You may omit the double-quotes in"#0", they are only needed here to trick the syntax highlighter.
– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of thebarprocs (a b c d) ever get set? Does that happen when i sourcebar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?
– the_meter413
Nov 12 at 17:35
1
Yes, when you sourcebar.tcl(as shown above), they are created in the top-level (global) namespace.
– mrcalvin
Nov 12 at 22:31
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.
Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:
upvar "#0" a alpha
This is equivalent to using global a modulo a variable alias (alpha).
You may omit the double-quotes in"#0", they are only needed here to trick the syntax highlighter.
– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of thebarprocs (a b c d) ever get set? Does that happen when i sourcebar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?
– the_meter413
Nov 12 at 17:35
1
Yes, when you sourcebar.tcl(as shown above), they are created in the top-level (global) namespace.
– mrcalvin
Nov 12 at 22:31
add a comment |
up vote
2
down vote
accepted
When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.
Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:
upvar "#0" a alpha
This is equivalent to using global a modulo a variable alias (alpha).
You may omit the double-quotes in"#0", they are only needed here to trick the syntax highlighter.
– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of thebarprocs (a b c d) ever get set? Does that happen when i sourcebar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?
– the_meter413
Nov 12 at 17:35
1
Yes, when you sourcebar.tcl(as shown above), they are created in the top-level (global) namespace.
– mrcalvin
Nov 12 at 22:31
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.
Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:
upvar "#0" a alpha
This is equivalent to using global a modulo a variable alias (alpha).
When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.
Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:
upvar "#0" a alpha
This is equivalent to using global a modulo a variable alias (alpha).
answered Nov 10 at 23:58
mrcalvin
1,044612
1,044612
You may omit the double-quotes in"#0", they are only needed here to trick the syntax highlighter.
– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of thebarprocs (a b c d) ever get set? Does that happen when i sourcebar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?
– the_meter413
Nov 12 at 17:35
1
Yes, when you sourcebar.tcl(as shown above), they are created in the top-level (global) namespace.
– mrcalvin
Nov 12 at 22:31
add a comment |
You may omit the double-quotes in"#0", they are only needed here to trick the syntax highlighter.
– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of thebarprocs (a b c d) ever get set? Does that happen when i sourcebar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?
– the_meter413
Nov 12 at 17:35
1
Yes, when you sourcebar.tcl(as shown above), they are created in the top-level (global) namespace.
– mrcalvin
Nov 12 at 22:31
You may omit the double-quotes in
"#0", they are only needed here to trick the syntax highlighter.– mrcalvin
Nov 11 at 0:01
You may omit the double-quotes in
"#0", they are only needed here to trick the syntax highlighter.– mrcalvin
Nov 11 at 0:01
So, tangential question, how do the variables outside the scope of the
bar procs (a b c d) ever get set? Does that happen when i source bar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?– the_meter413
Nov 12 at 17:35
So, tangential question, how do the variables outside the scope of the
bar procs (a b c d) ever get set? Does that happen when i source bar.tcl? In other words, how do I/am I actually making those variables global with the code above, or is there an additional bit of info I need to include?– the_meter413
Nov 12 at 17:35
1
1
Yes, when you source
bar.tcl (as shown above), they are created in the top-level (global) namespace.– mrcalvin
Nov 12 at 22:31
Yes, when you source
bar.tcl (as shown above), they are created in the top-level (global) namespace.– mrcalvin
Nov 12 at 22:31
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53243873%2ftcl-tk-scope-of-variables-for-a-function-within-a-function%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Your
returnlines throughoutfoo.tclandbar.tclshould provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValueinstead ofmyReturnValueetc.– mrcalvin
Nov 11 at 0:03