From: Andrew Wagner on 5 Aug 2010 12:18 [Note: parts of this message were removed to make it a legal post.] So if the do_stuff is in a format like this: def do_something
From: Martin Hansen on 5 Aug 2010 13:37 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/.
From: Andrew Wagner on 5 Aug 2010 17:13 [Note: parts of this message were removed to make it a legal post.] 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 <mail(a)maasha.dk> 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/. > >
From: Andrew Wagner on 5 Aug 2010 17:53 [Note: parts of this message were removed to make it a legal post.] 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<http://pragprog.com/screencasts/v-dtrubyom/the-ruby-object-model-and-metaprogramming> 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 <wagner.andrew(a)gmail.com>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 <mail(a)maasha.dk> 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/. > > > > >
From: Martin Hansen on 6 Aug 2010 04:26 I have been looking at your suggestions and done a few tests. However, I wonder if there is not a more simple way - and especially since these suggestions depends on methods being defined in order to invoke error handling. Here is a real life example of the type of minimalistic scripts I want to write: #!/usr/bin/env ruby require 'biopieces' casts = [] casts << {:long=>'compress',:short=>'Z',:type=>'flag',:mandatory=>false,:default=>nil,:allowed=>nil,:disallowed=>nil} bp = Biopieces.new options = bp.parse(ARGV,casts) bp.mktmpdir # create an optional temporary directory that is auto deleted. bp.each_record do |record| # do something to each record (possibly according to the options). e.g.: record["SEQ"].upcase! if record.has_key? "SEQ" bp.puts record raise # Debug test of invokation of error handling end Now, I would like error handling to be invoked, if possible from biopieces.rb, in the case some exception is raised (either by raise or ctrl-c, etc), but I am not defining any methods and thus the suggested meta-programming approaches seem to fall short. Cheers, Martin -- Posted via http://www.ruby-forum.com/.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Project name ownership and conflict Next: Used Car Sri Lanka |