Thomas Counsell
12/15/2004 8:46:00 PM
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
>
>