From: Thomas Counsell Date: 2004-12-16T05:45:59+09:00 Subject: Re: Can I make a new function like attr_accessor? Hi Paul Not tested, but something like this should do the trick: class Class def attr_emitter( *syms ) syms.each do |sym| class_eval( "def #{sym}; @#{sym} end" ) class_eval( "def #{sym}=(x) old, @#{sym} = @#{sym}, x emit(:#{sym}, old) end" ) end end end Note that I think you also need to define @listeners in your Emitter module ..... (@listeners ||= [] ).push( listener) or some such. Regards Tom On 15 Dec 2004, at 20:08, Jack, Paul wrote: > I'm writing a program that has a bunch of components I'd like > to link together using Java-style property change events. > > So I created a mixin module: > > module Emitter > > def addListener(listener) > @listeners.push(listener) > end > > def removeLister(listener) > @listeners.delete(listener) > end > > def emit(sym, oldValue) > @listeners.each { |x| x.propertyChanged(self, sym, oldValue) } > end > > end > > In my component objects, I just make them include Emitter and invoke > "emit" on any mutator: > > class ExampleComponent > > include Emitter > > def foo > @foo > end > > def foo=(x) > old = @foo > @foo = x > emit(:foo, old) > end > > end > > I'd like to automate the creation of emitter properties, though. Just > like I can use attr_accessor to quickly create readable/writeable > attributes, I'd like a new attr_emitter function to quickly create > readable/writeable/emitable attributes. > > But I can't figure out how to do that. :( Is it possible? It would > save me a LOT of redundant typing... > > Thanks all, > > -Paul > >