From: Andrew Wagner Date: 2010-08-06T06:53:04+09:00 Subject: Re: Abstracting exception handling --0016e6d99bfbd354cf048d1a90a0 Content-Type: text/plain; charset=UTF-8 For a somewhat more robust ErrorHandling module, which requires 1.9, try the code below. I should also give credit to the ruby metaprogramming screencast for inspiration for this code. It's practically ripped straight out of there, except theirs does tracing, as opposed to just error-handling. module ErrorHandling def self.included(klass) klass.instance_methods(false).each do |existing_method| wrap(klass, existing_method) end def klass.method_added(method) unless @watch_calls_internal @watch_calls_internal = true ErrorHandling.wrap(self, method) @watch_calls_internal = false end end end def self.wrap(klass, method) klass.class_eval do name = method.to_s original_method = instance_method(name) define_method(name) do |*args, &block| begin puts "attempting..." result = original_method.bind(self).call(*args, &block) rescue Exception ensure puts "last will..." end result end end end end On Thu, Aug 5, 2010 at 5:13 PM, Andrew Wagner wrote: > Ok, so here's something fairly simple to try. There are better ways to do > this, but this should work. In your error-handling file, put this: > > module ErrorHandling > def self.included(cls) > def cls.method_added(method) > return if @_adding_a_method > @_adding_a_method = true > > original_method = "original #{method}" > alias_method original_method, method > > define_method(method) do |*args| > begin > puts "gonna try something dangerous" > send original_method, *args > rescue Exception > ensure > puts "My last will and testament..." > end > end > > @_adding_a_method = false > end > end > end > > The idea is, when you include this module, then it watches for any new > methods you define. When you define one, it immediately hides it away, and > creates a new method, which calls the original one, but inside a > begin/rescue/ensure block. The @_adding_a_method flag is just to keep from > infinite recursion when you create the new method (because it will also > trigger method_added. > > Now in your main class, do something like this: > > include ErrorHandling > > def do_something > puts "do something dangerous" > end > > do_something > > On Thu, Aug 5, 2010 at 1:37 PM, Martin Hansen wrote: > > > Andrew Wagner wrote: > > > > > Then when you could do is have a module which overrides Ruby's method > > > that > > > gets called when you define a method. You can alias the method being > > > created > > > to something else, then define a new method which calls that one, but > > > wraps > > > it in whatever error-handling code you want. > > > > Sorry, I have no idea how to do that - it sounds terribly complicated. > > Is there no simple solution? Could you perhaps give a small example? > > > > > > Martin > > -- > > Posted via http://www.ruby-forum.com/. > > > > > --0016e6d99bfbd354cf048d1a90a0--