[Xotcl] Using uplevel within instprocs from instprocs

MichaelL at frogware.com MichaelL at frogware.com
Mon Nov 15 23:16:40 CET 2004


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.)


More information about the Xotcl mailing list