Contine after exception

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: