From: Michael Sullivan Date: 2001-11-15T11:48:49+09:00 Subject: [ruby-talk:25241] Re: attr_accessor question Avi, Thanks for getting back to me. We must be thinking along the same lines because this is what I've come up with: class Module def attr_callback(*accessors) accessors.each { |a| eval " def #{a}=(p) @#{a}=p self.respond_to?(attr_changed, TRUE) && attr_changed( :#{a} ) @#{a} end def #{a} @#{a} end" } end end class TestClass attr_callback :e end TestClass.instance_methods However, it seems to completely ignore the "eval". I've replaced the eval with a puts for testing and the methods appear to be formed correctly. When I go to see if the instance methods are defined, I get an empty array. BTW, I tried your variant making attr_notify a class method for Module, but it complains when defining Foo it cannot find attr_notify. Seems like it should work, but it doesn't. Any clues? Mike On Thu, Nov 15, 2001 at 10:38:39AM +0900, Avi Bryant wrote: > Michael Sullivan wrote: > > I was wondering if when one has defined "attr_accessor" for their > > instance variables if there was any way to determine when one of the > > variables changes. > > We really need a more generic attr framework, so that I can write something like > > class Foo > attr [:read, :write, :initialize, :notify] :x, :y > end > > (and while we're at it, we need to be able to do the same thing for methods > and classes...) > > But for now, how about: > > def Module.attr_notify(*vars) > vars.each do |var| > module_eval %{ > def #{var}() @#{var} end > def #{var}=(_#{var}) > @#{var} = _#{var} > changed(:#{var}) > end > } > end > end > > > This is untested, but it should allow: > > class Foo > attr_notify :x, :y > > def changed(var) > puts "#{var} was changed!" > end > end -- Michael P. Sullivan Distributed Computing Systems, LLC Cell: 516-429-2080 E-Mail: mps@discomsys.com http://www.discomsys.com/ * UNIX Systems and Database Consulting, Architecture and Management * "Failing to plan, is planning to fail... plan for the worst, hope for the best"