Morton Goldberg
7/22/2006 9:49:00 AM
Thanks, I think I understand now. And I agree that having access to
the local variables of the try block is a Really Good Thing.
But don't you think it would be clearer if you called the accessor
"block" rather than "binding". After all, its a Proc object not a
Binding object that's returned by err.binding. To actually get at the
value of the block variable, one has to apply Proc#binding to what
err.binding returns, giving err.binding.binding, which I find
somewhat confusing. I think code using your continuable exception
would read better with err.block.binding. See modified code below.
Regards, Morton
module Exception::Continuable
def try &bl
bl.call
rescue Exception => exp
callcc do |cc|
exp.instance_variable_set(:@continuation, cc)
exp.instance_variable_set(:@block, bl) # change
class << exp
attr_reader :continuation, :block # change
def continue
@continuation.call
end
end
raise exp
end
end
end
# ...
begin
[1,2,3,4,5,6,7,8].each{|v| try do printStuff(v) end}
rescue RetryException => err
puts "inside retry rescue"
what = eval('v', err.block.binding) # new
puts "try block working on #{what}" # new
puts "going back to try block" # new
err.continue
rescue
puts "other exception"
ensure
puts "inside ensure"
end
which produces
printing 1
printing 2
printing 3
inside retry rescue
try block working on 3
going back to try block
printing 4
printing 5
printing 6
printing 7
printing 8
inside ensure
On Jul 22, 2006, at 12:35 AM, Csaba Henk wrote:
> Yeah, it's irrelevant as far as the actual problem is considered.
> However, I wanted to make Exception::Continuable generic (in fact, I
> have already had it at hand).
>
> It seems to be handy to be able to examine the situation where the
> badness happened, so that we can decide if we really want to continue
> from after the exception or let just abort that branch.
>
> Having access to the bindings of the location where the exception
> has been
> raised can help you in that analysis.