Class-wide begin/end blocks/exception handling

So I have a class with a lot of methods, and each method has a begin/end
block

class HiThere
def one(stext)
  begin
   puts("Hi");
  rescue Exception => msg
   self.exceptionHandle(msg)
  end
end

def two(stext)
  begin
   puts("Hi");
  rescue Exception => msg
   self.exceptionHandle(msg)
  end
end

#etc etc
#...
end

... Is there a way to put one begin/end block encompassing the whole
class/object? Sort of like an instance-wide begin/end block?

hehe<--- but serious...

···

--
Posted via http://www.ruby-forum.com/.

There isn't any syntax that lets you rescue any exception for the whole class, but you can add a rescue clause to an entire method, saving you a 'begin' and an 'end'. E.g., instead of:

   def one(stext)
     begin
       puts("Hi");
     rescue Exception => msg
       self.exceptionHandle(msg)
     end
   end

you'd have:

   def one(stext)
     puts("Hi");
   rescue Exception => msg
     self.exceptionHandle(msg)
   end

This is (IMO) far more readable than the alternative.

You could probably add exception-handling for any method on a whole class using clever aliasing and the 'method_added' hook or a declarative, but down that path lies madness in the face of ScriptErrors or any exception you haven't anticipated.

···

On 11/29/10 4:06 PM, David E. wrote:
> [...]
> ... Is there a way to put one begin/end block encompassing the whole
> class/object? Sort of like an instance-wide begin/end block?

--
Michael Granger <ged@FaerieMUD.org>
Rubymage, Architect, Believer
The FaerieMUD Consortium <http://FaerieMUD.org/>

Not directly, but you can do

# needs 1.9
class Proxy < BasicObject
  def initialize(obj)
    @obj = obj
  end

  def method_missing(*a,&b)
    @obj.send(*a,&b)
  rescue ::Exception => e
    handle_exception e
  end

  def handle_exception(e)
    puts e.message
  end
end

irb(main):016:0> s = "foo"
=> "foo"
irb(main):017:0> s + "bar"
=> "foobar"
irb(main):018:0> s + 99
TypeError: can't convert Fixnum into String
        from (irb):18:in `+'
        from (irb):18
        from /opt/bin/irb19:12:in `<main>'
irb(main):019:0> pr = Proxy.new(s)
=> "foo"
irb(main):020:0> pr + "bar"
=> "foobar"
irb(main):021:0> pr + 99
can't convert Fixnum into String
=> nil
irb(main):022:0>

HTH

Kind regards

robert

···

On Tue, Nov 30, 2010 at 1:06 AM, David E. <davidreynon@gmail.com> wrote:

So I have a class with a lot of methods, and each method has a begin/end
block

class HiThere
def one(stext)
begin
puts("Hi");
rescue Exception => msg
self.exceptionHandle(msg)
end
end

def two(stext)
begin
puts("Hi");
rescue Exception => msg
self.exceptionHandle(msg)
end
end

#etc etc
#...
end

... Is there a way to put one begin/end block encompassing the whole
class/object? Sort of like an instance-wide begin/end block?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Even better

class Proxy < BasicObject
  def initialize(obj, &handler)
    @obj = obj
    @handler = handler
  end

  def method_missing(*a,&b)
    @obj.send(*a,&b)
  rescue ::Exception => e
    @handler and @handler[e]
  end
end

def Proxy(obj, &handler)
  Proxy.new(obj, &handler)
end

irb(main):016:0> s = "foo"
=> "foo"
irb(main):017:0> s + "bar"
=> "foobar"
irb(main):018:0> s + 99
TypeError: can't convert Fixnum into String
        from (irb):18:in `+'
        from (irb):18
        from /opt/bin/irb19:12:in `<main>'
irb(main):019:0> pr = Proxy(s) {|e| p e.message}
=> "foo"
irb(main):020:0> pr + "bar"
=> "foobar"
irb(main):021:0> pr + 99
"can't convert Fixnum into String"
=> "can't convert Fixnum into String"
irb(main):022:0>

Cheers

robert

···

On Tue, Nov 30, 2010 at 3:39 PM, Robert Klemme <shortcutter@googlemail.com> wrote:

On Tue, Nov 30, 2010 at 1:06 AM, David E. <davidreynon@gmail.com> wrote:

So I have a class with a lot of methods, and each method has a begin/end
block

class HiThere
def one(stext)
begin
puts("Hi");
rescue Exception => msg
self.exceptionHandle(msg)
end
end

def two(stext)
begin
puts("Hi");
rescue Exception => msg
self.exceptionHandle(msg)
end
end

#etc etc
#...
end

... Is there a way to put one begin/end block encompassing the whole
class/object? Sort of like an instance-wide begin/end block?

Not directly, but you can do

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/