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…

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?

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 Tue, Nov 30, 2010 at 1:06 AM, David E. [email protected] wrote:

end
#…
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

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
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 3:39 PM, Robert K.
[email protected] wrote:

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

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