[Xotcl] Catching errors in calls to "next"

MichaelL at frogware.com MichaelL at frogware.com
Mon Nov 15 18:41:25 CET 2004


I'm using XOTcl 1.3.1. (I haven't upgraded to the 1.3.3 beta yet.)

I have a filter that does work before and after calls to "next". I'd like 
to make sure that the "after" code always gets called, so I'm using 
"catch" around my call to "next," a bit like this:

        # do something before

        set err [catch {next} result]

        # do something after

The problem is that in specific circumstances (when objects are 
constructed) the fact that "next" is called within "catch" is screwing 
things up. (The error I'm getting is "5", which is defined in XOTcl as 
"XOTCL_UNKNOWN".)

I can see why "catch" would get in the way, but so far I haven't found a 
way around the problem. Does anyone have any ideas?

Here's some sample code. TestA works (as expected), but TestB doesn't.

    Object instproc someFilterA {args} {
        puts "self class       = [self class]"
        puts "self             = [self]"
        puts "self calledclass = [self calledclass]"
        puts "self calledproc  = [self calledproc]"
        puts "args             = $args"
        puts ""

        set err    0
        set result [next]

        if {$err==0 || $err==2 || $err==3 || $err==4} {
            # 0 = OK
            # 2 = Return
            # 3 = Break
            # 4 = Continue
            return             $result
        } else {
            # 1 = Error
            # * = Error (user-defined)
            return -code error $result
        }

    }

    Object instproc someFilterB {args} {
        puts "self class       = [self class]"
        puts "self             = [self]"
        puts "self calledclass = [self calledclass]"
        puts "self calledproc  = [self calledproc]"
        puts "args             = $args"
        puts ""

        set err [catch {next} result]

        if {$err==0 || $err==2 || $err==3 || $err==4} {
            # 0 = OK
            # 2 = Return
            # 3 = Break
            # 4 = Continue
            return             $result
        } else {
            # 1 = Error
            # * = Error (user-defined)
            return -code error $result
        }

    }

    puts "*** Initializing..."
    puts ""

    Class TestA -parameter {{x 0}} -filter someFilterA

    TestA instproc err {} {
        expr {5/0}
    }

    Class TestB -parameter {{x 0}} -filter someFilterB

    TestB instproc err {} {
        expr {5/0}
    }

    puts "*** Starting..."
    puts ""

    TestA ::a -x 5
    a x
    a x 10
    #a err

    puts ""
    puts "----------"
    puts ""

    TestB ::b -x 5
    b x
    b x 10
    #b err

    puts "*** Finished."

The relevant part of the output is:

*** Starting...

self class       = ::xotcl::Object
self             = ::TestA
self calledclass =
self calledproc  = ::a
args             = -x 5

self class       = ::xotcl::Object
self             = ::TestA
self calledclass = ::xotcl::Class
self calledproc  = unknown
args             = ::a -x 5

self class       = ::xotcl::Object
self             = ::TestA
self calledclass = ::xotcl::Class
self calledproc  = create
args             = ::a -x 5

self class       = ::xotcl::Object
self             = ::TestA
self calledclass = ::xotcl::Class
self calledproc  = alloc
args             = ::a -x 5

----------

self class       = ::xotcl::Object
self             = ::TestB
self calledclass =
self calledproc  = ::b
args             = -x 5


    ::TestB ::xotcl::Object->someFilterB
    invoked from within
"TestB ::b -x 5"
    invoked from within
"if 1 {
    Object instproc someFilterA {args} {
        puts "self class       = [self class]"
        puts "self             = [self]"
        puts "..."
    (file "XOTcl-test.tcl" line 7)
self class       = ::xotcl::Object
self             = ::TestA
self calledclass = ::xotcl::Class
self calledproc  = instdestroy
args             = ::a

self class       = ::xotcl::Object
self             = ::TestA
self calledclass = ::xotcl::Object
self calledproc  = destroy
args             =

self class       = ::xotcl::Object
self             = ::TestB
self calledclass = ::xotcl::Object
self calledproc  = destroy
args             =



More information about the Xotcl mailing list