No registered users in community xowiki
in last 10 minutes
in last 10 minutes
[Xotcl] Using uplevel within instprocs from instprocs
From: <MichaelL_at_frogware.com>
Date: Mon, 15 Nov 2004 17:16:40 -0500
I've defined a proc which is supposed to be a control structure that
iterates over the children of an object. There's a problem, though, when I
nest calls.
Here's some code:
Object instproc each {objName body} {
puts " *** level = [info level]"
puts " *** self callinglevel = [self callinglevel]"
uplevel [self callinglevel] [list foreach $objName [lsort [[self]
info children]] $body]
}
Class TestB
Class TestA
TestA instproc init {args} {
next
TestB [self]::b1
TestB [self]::b2
TestB [self]::b3
}
Class Test
Test instproc init {args} {
next
TestA [self]::a1
TestA [self]::a2
TestA [self]::a3
}
Test instproc loop1 {} {
set i 0
[self] each a {
incr i
puts "$a"
}
puts "Total = $i"
}
Test instproc loop2 {} {
set i 0
[self] each a {
incr i
puts "$a"
$a each b {
incr i
puts " $b"
}
}
puts "Total = $i"
}
Test t
t loop1
t loop2
Here's some output:
*** level = 2
*** self callinglevel = #1
::t::a1
::t::a2
::t::a3
Total = 3
*** level = 2
*** self callinglevel = #1
::t::a1
*** level = 2
*** self callinglevel = #2
can't read "i": no such variable
(reading value of variable to increment)
invoked from within
"incr i"
("foreach" body line 2)
invoked from within
"foreach b {::t::a1::b1 ::t::a1::b2 ::t::a1::b3} {
incr i
puts " $b"
}"
("uplevel" body line 1)
invoked from within
"uplevel [self callinglevel] [list foreach $objName [lsort [[self] info
children
]] $body]"
(procedure "each" line 5)
::t::a1 ::xotcl::Object->each
invoked from within
"$a each b {
incr i
puts " $b"
}"
("foreach" body line 4)
invoked from within
"foreach a {::t::a1 ::t::a2 ::t::a3} {
incr i
puts "$a"
$a each b {
incr i
puts " ..."
("uplevel" body line 1)
invoked from within
"uplevel [self callinglevel] [list foreach $objName [lsort [[self] info
children
]] $body]"
(procedure "each" line 5)
::t ::xotcl::Object->each
invoked from within
"[self] each a {
incr i
puts "$a"
$a each b {
incr i
puts " $b"
}
..."
(procedure "loop2" line 4)
::t ::Test->loop2
invoked from within
"t loop2"
invoked from within
"if 1 {
Object instproc each {objName body} {
puts " *** level = [info level]"
puts " *** self callinglevel = [self cal..."
(file "XOTcl-test.tcl" line 7)
You can see that the one-level iterator succeeds, but the two-level
iterator can't see the variable defined in the outer loop. You can also
see that the first time "level" and "callinglevel" are different (as you
would expect) but the second time they're the same (which looks like it
might be an XOTcl bug). Any ideas?
(I can work around this for now, of course, but it would be nice to figure
out what's wrong.)
Date: Mon, 15 Nov 2004 17:16:40 -0500
I've defined a proc which is supposed to be a control structure that
iterates over the children of an object. There's a problem, though, when I
nest calls.
Here's some code:
Object instproc each {objName body} {
puts " *** level = [info level]"
puts " *** self callinglevel = [self callinglevel]"
uplevel [self callinglevel] [list foreach $objName [lsort [[self]
info children]] $body]
}
Class TestB
Class TestA
TestA instproc init {args} {
next
TestB [self]::b1
TestB [self]::b2
TestB [self]::b3
}
Class Test
Test instproc init {args} {
next
TestA [self]::a1
TestA [self]::a2
TestA [self]::a3
}
Test instproc loop1 {} {
set i 0
[self] each a {
incr i
puts "$a"
}
puts "Total = $i"
}
Test instproc loop2 {} {
set i 0
[self] each a {
incr i
puts "$a"
$a each b {
incr i
puts " $b"
}
}
puts "Total = $i"
}
Test t
t loop1
t loop2
Here's some output:
*** level = 2
*** self callinglevel = #1
::t::a1
::t::a2
::t::a3
Total = 3
*** level = 2
*** self callinglevel = #1
::t::a1
*** level = 2
*** self callinglevel = #2
can't read "i": no such variable
(reading value of variable to increment)
invoked from within
"incr i"
("foreach" body line 2)
invoked from within
"foreach b {::t::a1::b1 ::t::a1::b2 ::t::a1::b3} {
incr i
puts " $b"
}"
("uplevel" body line 1)
invoked from within
"uplevel [self callinglevel] [list foreach $objName [lsort [[self] info
children
]] $body]"
(procedure "each" line 5)
::t::a1 ::xotcl::Object->each
invoked from within
"$a each b {
incr i
puts " $b"
}"
("foreach" body line 4)
invoked from within
"foreach a {::t::a1 ::t::a2 ::t::a3} {
incr i
puts "$a"
$a each b {
incr i
puts " ..."
("uplevel" body line 1)
invoked from within
"uplevel [self callinglevel] [list foreach $objName [lsort [[self] info
children
]] $body]"
(procedure "each" line 5)
::t ::xotcl::Object->each
invoked from within
"[self] each a {
incr i
puts "$a"
$a each b {
incr i
puts " $b"
}
..."
(procedure "loop2" line 4)
::t ::Test->loop2
invoked from within
"t loop2"
invoked from within
"if 1 {
Object instproc each {objName body} {
puts " *** level = [info level]"
puts " *** self callinglevel = [self cal..."
(file "XOTcl-test.tcl" line 7)
You can see that the one-level iterator succeeds, but the two-level
iterator can't see the variable defined in the outer loop. You can also
see that the first time "level" and "callinglevel" are different (as you
would expect) but the second time they're the same (which looks like it
might be an XOTcl bug). Any ideas?
(I can work around this for now, of course, but it would be nice to figure
out what's wrong.)