From: David Alan Black Date: 2002-08-05T08:29:06+09:00 Subject: Re: Detecting when an instance variable is created/set Hi -- On Mon, 5 Aug 2002, Harry Ohlsen wrote: > > > Unfortunately, for it to be useful to me, I'd specifically need it to > > > work in initialize() as well. > > > > I don't know why it does not work in initialize (I assumed it would). > > A dirty fix: > > > > module Initializer > > def initialize(*args) > > puts "Here I'll handle these variables: #{instance_variables.inspect}" > > end > > end > > > > module MonitorVariables > > ... > > end > > > > class Test > > def initialize(*args) > > @a = 1 > > @b = 'world' > > super(*args) > > end > > What is that super() calling? It seems to be the initialize() in Initializer, > but I don't understand why. I would have thought that it would be calling > the one from perhaps Object (since Test doesn't specifically subclass > anything else). > > > I also don't know why, if put in MonitorVariables, initialize won't be > > called, and needs to be put in a different module. > > I added the code in your Initializer module into MonitorVariables and it > worked OK, so while it seems initialize() seems to need to be handled > separately, it doesn't appear to need to be in a different module. My experience was the same as Massimiliano's: the #initialize didn't seem to get found by 'super' if it was in the same module as #append_features. I don't know why not. (On #initialize being handled separately -- see earlier post about private methods.) > I still have the issue, though, that with this module included, all of the > instance variables end up being set to "true", rather than to the values they > were actually assigned. > > Any idea why that is and how to fix it? Yes -- the dynamically created replacement methods in M.'s append_features method aren't returning the value of the call to the original method. Here's what I think is a drop-in replacement (a few variable names tweaked just to conform to my habits while hacking :-) module MonitorVariables def self.append_features(klass) (klass.instance_methods + ['initialize']).each do |method| oldmeth = "___#{method}" klass.class_eval <<-EOF alias #{oldmeth} #{method} def #{method}(*params,&block) old_iv = instance_variables res = #{oldmeth}(*params,&block) (diff = instance_variables - old_iv).empty? or puts "variable(s) " + diff.inspect + " added in method #{method}" return res end EOF end end end I'm wondering, though, whether there's a simpler way to do what you're trying to do (the self.a = x approach maybe?). David -- David Alan Black home: dblack@candle.superlink.net work: blackdav@shu.edu Web: http://pirate.shu.edu/~blackdav