"Thomas Counsell" <tamc2 / cam.ac.uk> schrieb im Newsbeitrag news:4BEB5F89-4EDA-11D9-B9F5-000393CC0FA0 / cam.ac.uk... > 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 Preferrable put that code into class Module. That way even modules can use attr_emitter. > Note that I think you also need to define @listeners in your Emitter > module ..... (@listeners ||= [] ).push( listener) or some such. Yeah. Also you can automate inclusion of the module. So this would be my implementation: module Emitter def listeners; @listeners ||= [] end 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 class Module def attr_emitter(*syms) syms.each do |sym| class_eval( "def #{sym}; @#{sym} end; def #{sym}=(x) old, @#{sym} = @#{sym}, x ; emit(:#{sym}, old) end" ) end include Emitter end end Kind regards robert