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.tcl
that I want to use in both procsbar1
andbar2,
and - call
bar1
andbar2
from 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.tcl
that I want to use in both procsbar1
andbar2,
and - call
bar1
andbar2
from 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
Yourreturn
lines throughoutfoo.tcl
andbar.tcl
should provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValue
instead ofmyReturnValue
etc.
– 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.tcl
that I want to use in both procsbar1
andbar2,
and - call
bar1
andbar2
from 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.tcl
that I want to use in both procsbar1
andbar2,
and - call
bar1
andbar2
from 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
Yourreturn
lines throughoutfoo.tcl
andbar.tcl
should provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValue
instead ofmyReturnValue
etc.
– mrcalvin
Nov 11 at 0:03
add a comment |
1
Yourreturn
lines throughoutfoo.tcl
andbar.tcl
should provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValue
instead ofmyReturnValue
etc.
– 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 thebar
procs (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 thebar
procs (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 thebar
procs (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 thebar
procs (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 thebar
procs (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
return
lines throughoutfoo.tcl
andbar.tcl
should provide for variable substitution. Right now, they return literally the variable names. Write$myReturnValue
instead ofmyReturnValue
etc.– mrcalvin
Nov 11 at 0:03