From: Robert Feldt Date: 2001-06-18T06:56:05+09:00 Subject: [ruby-talk:16579] Re: Trapping method defs On Sat, 16 Jun 2001, Mathieu Bouchard wrote: > > ? RCR? Or one can easily get it from 'caller' as in my previously > > proposed call_stack RCR... > > Not sure how you'd do that... I don't think "def" will appear in the > call stack. I expect something weird to happen, like a half-blank > entry or a missing entry or two half-missing entries (e.g. Ruby code > appears to be calling method_added itself...) but that's pure speculation. > Ok. Matz? > > I sure hope this is already supported in some way I've missed... > > I have played a bit with #method_added a few weeks ago... > > def Integer.method_added(sym) > if sym==:% > puts "I find your lack of faith... disturbing" > Process.kill 11, Process.pid > end > end > > but then, Hurst and I figured out that: > > a. #method_added can be redefined or removed without your #method_added > being actually called. > > b. unless you freeze Module ;-) > > c. doesn't prevent anyone from def'ing a singleton #method_added without > you getting to know anything about it. > Can't I use Object.singleton_method_added? > d. you still don't have info about the replaced method... > > sorry, haven't pushed this further. > Maybe if you continue on something like: class Object def Object.method_added(methodId) puts "ORG: Added method #{self.inspect}##{methodId.id2name}" end @@defining_method_added = false def Object.singleton_method_added(methodId) if methodId == :method_added if @@defining_method_added @@defining_method_added = false else puts "Added singleton method #{self.inspect}.#{methodId.id2name}" @@defining_method_added = true # Reinstall our method_added! self.instance_eval <<-'EOC' alias new_method_added method_added def method_added(methodId) new_method_added(methodId) puts "REI: Added method #{self.inspect}##{methodId.id2name}" end EOC end else unless self == Object and methodId == :singleton_method_added puts "Added singleton method #{self.inspect}.#{methodId.id2name}" end end end end class C def im1 end def C.method_added(methodId) puts "C: Added method #{self.inspect}##{methodId.id2name}" end def im2 end end but you'll have to reinstall the singleton_method_added in singleton_method_added if someone tries to redef Object.singleton_method_added. And then they can probably use undef_method and/or remove_method anyway and on it goes... Maybe there is not a fully "safe" way but my alternative is to use a trace func and then it wont work if someone sets another trace func... (and I can't afford the typical factor 50 slowdown of using trace funcs). Anyway thanks for your input! /Robert