[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

contine after exception

junkone

7/21/2006 8:17:00 PM

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

7 Answers

Brian Schröder

7/21/2006 8:36:00 PM

0

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

--
http://ruby.brian-sch...

Stringed instrument chords: http://chordlist.brian-sch...

Csaba Henk

7/21/2006 11:19:00 PM

0

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

Do you think of something like this?

#############################################

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

Morton Goldberg

7/22/2006 12:56:00 AM

0

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


Csaba Henk

7/22/2006 4:31:00 AM

0

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.

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

Morton Goldberg

7/22/2006 9:49:00 AM

0

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.


Csaba Henk

7/22/2006 10:19:00 AM

0

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.


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

Morton Goldberg

7/22/2006 2:19:00 PM

0

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:

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