How do i continue a loop after a exception? It actually captures the
exception . How do i get the exception handler to start executing from
4 to call the printstuff function?
def printStuff(inpu) ## just print stuff
puts "printing" + inpu.to_s
if (inpu==3)
raise RetryException.new(true)
end
# raise RuntimeError
end
def enter1
begin
[1,2,3,4,5,6,7,8].each{|value| printStuff(value)}#call function
to print.
rescue RetryException
puts " inside rescuedo nothing"
###QUESTION: how to continue calling
#puts dd.okToRetry
rescue
puts "other exception"
ensure
puts "insode ensire"
end
end
end
Try with
(1..8).each do | value |
begin
raise "Exception" if value == 3
puts value
rescue
puts "That was exceptional"
end
end
cheers,
Brian
···
On 21/07/06, junkone@rogers.com <junkone@rogers.com> wrote:
How do i continue a loop after a exception? It actually captures the
exception . How do i get the exception handler to start executing from
4 to call the printstuff function?
def printStuff(inpu) ## just print stuff
puts "printing" + inpu.to_s
if (inpu==3)
raise RetryException.new(true)
end
# raise RuntimeError
end
def enter1
begin
[1,2,3,4,5,6,7,8].each{|value| printStuff(value)}#call function
to print.
rescue RetryException
puts " inside rescuedo nothing"
###QUESTION: how to continue calling
#puts dd.okToRetry
rescue
puts "other exception"
ensure
puts "insode ensire"
end
--
http://ruby.brian-schroeder.de/
Stringed instrument chords: http://chordlist.brian-schroeder.de/
Do you think of something like this?
···
On 2006-07-21, junkone@rogers.com <junkone@rogers.com> wrote:
How do i continue a loop after a exception? It actually captures the
exception . How do i get the exception handler to start executing from
4 to call the printstuff function?
def printStuff(inpu) ## just print stuff
puts "printing" + inpu.to_s
if (inpu==3)
raise RetryException.new(true)
end
# raise RuntimeError
end
def enter1
begin
[1,2,3,4,5,6,7,8].each{|value| printStuff(value)}#call function
to print.
rescue RetryException
puts " inside rescuedo nothing"
###QUESTION: how to continue calling
#puts dd.okToRetry
rescue
puts "other exception"
ensure
puts "insode ensire"
end
end
end
#############################################
module Exception::Continuable
def try &bl
bl.call
rescue Exception => exp
callcc do |cc|
exp.instance_variable_set :@continuation, cc
exp.instance_variable_set :@binding, bl
class << exp
attr_reader :continuation, :binding
def continue
@continuation.call
end
end
raise exp
end
end
end
class Object
include Exception::Continuable
end
class RetryException < Exception
end
def printStuff(inpu) ## just print stuff
puts "printing" + inpu.to_s
if inpu == 3
raise RetryException
end
end
begin
[1,2,3,4,5,6,7,8].each{|value| try do printStuff(value) end }
rescue RetryException => err
puts " inside rescuedo nothing"
err.continue
rescue
puts "other exception"
ensure
puts "insode ensire"
end
===========>
printing1
printing2
printing3
inside rescuedo nothing
printing4
printing5
printing6
printing7
printing8
insode ensire
#############################################
Regards,
Csaba
I think I understand most of what you are doing here, and I think it's very nice. The one point that eludes me is purpose of the line:
exp.instance_variable_set :@binding, bl
Could you explain that. The code seems to work just fine even when that line is commented out.
Regards, Morton
···
On Jul 21, 2006, at 7:20 PM, Csaba Henk wrote:
module Exception::Continuable
def try &bl
bl.call
rescue Exception => exp
callcc do |cc|
exp.instance_variable_set :@continuation, cc
exp.instance_variable_set :@binding, bl
class << exp
attr_reader :continuation, :binding
def continue
@continuation.call
end
end
raise exp
end
end
end
class Object
include Exception::Continuable
end
class RetryException < Exception
end
def printStuff(inpu) ## just print stuff
puts "printing" + inpu.to_s
if inpu == 3
raise RetryException
end
end
begin
[1,2,3,4,5,6,7,8].each{|value| try do printStuff(value) end }
rescue RetryException => err
puts " inside rescuedo nothing"
err.continue
rescue
puts "other exception"
ensure
puts "insode ensire"
end
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.
Regards,
Csaba
···
On 2006-07-22, Morton Goldberg <m_goldberg@ameritech.net> wrote:
I think I understand most of what you are doing here, and I think
it's very nice. The one point that eludes me is purpose of the line:
exp.instance_variable_set :@binding, bl
Could you explain that. The code seems to work just fine even when
that line is commented out.
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.
Well, you don't have to write err.binding.binding, because a proc
can be used as a binding as-is:
def foo &bl
eval "x", bl
end
x = 5
foo {} ==> 5
Yet it's true that a proc has more in it than a binding, moreover we can make
use of this extra in the context of continuable exceptions -- eg., after
some kind of sanitization we might retry the "try" guarded action by
calling the block. That wouldn't happen if we just continued from the
error.
So, yes, eventually I argree that it's better to call that block
"block".
Regards,
Csaba
···
On 2006-07-22, Morton Goldberg <m_goldberg@ameritech.net> wrote:
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.
I didn't know that (obviously :), but now that I've looked it up in the Pickaxe book, I see that it's mentioned. Is that behavior new to 1.8? Or is it Proc#binding that's new?
Although I find your try with a continuable exception a fine example of something can be done rather easily in Ruby that would be difficult or impossible in most other programming languages, I think it's more. I think it's likely I'll put it to practical use some day. Thanks again.
There is a lot about Ruby I've yet to learn. This thread has been very educational for me.
Regards, Morton
···
On Jul 22, 2006, at 6:20 AM, Csaba Henk wrote:
Well, you don't have to write err.binding.binding, because a proc
can be used as a binding as-is: