It seems that exception handlers get tied to
subroutines when they're created, not when
they're actually used. For example:
## this works:
try:
f = make_function()
f.die() # raise some error
except:
pass
## this does not work:
f = make_function()
try:
f.die() # raise some error
except:
pass
This is a problem in general, but especially for me
because in python, a generator returns an object,
and you call that object's next() over and over
until you get a StopIteration. Unfortunately, I
can't *trap* that StopIteration in a "try" block
unless I create the generator inside that same block.
Following is a detailed test case in imc that
illustrates the problem.
Sincerely,
Michal J Wallace
Sabren Enterprises, Inc.
-------------------------------------
contact: [EMAIL PROTECTED]
hosting: http://www.cornerhost.com/
my site: http://www.withoutane.com/
--------------------------------------
## generator_try_bug.imc
## this exposes a bug in parrot exception handling
## a function returns a function and that function
## throws an error. The error is not caught.
.sub __main__
new_pad 0
# count() returns a generator
.local object count
newsub count, .Closure, _count
# here's where we'll store it
.local object generator
# if "try:" is around the CREATION of the generator,
# everything works fine. but we don't want that, so
# this is commented out.
#
# .local Sub handler
# newsub handler, .Exception_Handler, catch0
# set_eh handler
# call count and get the generator
.local Sub retlabel0
newsub retlabel0, .Continuation, ret0
.pcc_begin non_prototyped
.pcc_call count, retlabel0
ret0:
.result generator
.pcc_end
## HERE IS where we want the try block to start ####
.local Sub handler
newsub handler, .Exception_Handler, catch0
set_eh handler
# now call the generator, which throws 'StopIteration'
.local Sub retlabel1
newsub retlabel1, .Continuation, ret1
.pcc_begin non_prototyped
.pcc_call generator, retlabel1
ret1:
.result $P3
.pcc_end
# end the "try" block (we never get here)
clear_eh
goto endtry0
catch0:
print "caught it!"
endtry0:
end
.end
# here is count(), which returns the generator
.pcc_sub _count non_prototyped
.local object gen_fun
.local object gen_obj
newsub gen_fun, .Coroutine, _count_g
.pcc_begin_return
.return gen_fun
.pcc_end_return
.end
# here is the generator itself
# all it does is throw StopIteration
.pcc_sub _count_g non_prototyped
.local object ex0
.local object msg0
ex0 = new Exception
msg0 = new PerlString
msg0 = 'StopIteration'
ex0['_message'] = msg0
throw ex0
.end
## end of test case ###############################