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.