benny
11/4/2004 3:44:00 PM
dear list,
maybe I am a bit dump, but the code was only a part of the solution, right?
so I tried to paint the rest of the picture and this was the only way I
could figure out how the "core" may fit into the rest.
(some classes and Try#initialize and Try#add_exhandler were missing,
exhandlers is now attribute etc.)
I'm just curious if this was the way you all thought about it or if I did
miss an easier solution .
regards,
benny
######## the code ###########
# general error class
class Error < RuntimeError
attr_accessor :exception_handler
def initialize(code)
code.call(self)
end
end
# some specific self defined error class
class TestError < Error
attr_accessor :msg
def initialize(msg = nil , &code)
super(code) if code
@msg = msg
end
end
# the Try class
class Try
def initialize(*args, &code)
@user_proc = code
@user_proc_args = *args
@exhandlers = []
end
def add_exhandler(name, &block)
eval("@exhandlers << #{name.to_s}.new() do |obj| obj.exception_handler =
block; end")
end
def execute
@user_proc.call(@user_proc_args)
rescue Error => e
elt = (@exhandlers.select{|obj| e.kind_of? obj.class })[0] or raise
elt.exception_handler.call(e)
end
end
######################
# a test
tryblock = Try.new {
puts "doing something..."
raise TestError, "my favorite error message"
#raise "some other error"
}
tryblock.add_exhandler(:TestError) { | ex |
puts "TestError raised!
\n\tbacktrace:#{ex.backtrace}\n\tmessage:'#{ex.msg}'"
}
tryblock.execute
Yohanes Santoso wrote:
> "Robert Klemme" <bob.news@gmx.net> writes:
>
>>> class Try
>>> def execute
>>> user_proc.call(*user_proc_args)
>>> rescue Error => e
>>> elt = (exhandlers.select{|obj| e.class == obj.exception_class})[0]
>> or raise
>>> elt.exception_handler.call(e)
>>> end
>>> end
>
> Nice! But I think I have left out an important factor in the original
> solution. It shouldn't be e.class == obj.exception_class, but rather
> e.kind_of?(obj.exception_class).
>
> YS.