Can I make a new function like attr_accessor? (solved)

BTW, if you're just coming from Ruby to Java, I wrote an
article on my blog that you might find really useful:
http://fhwang.net/blog/40.html

Thanks. If nothing else, I've changed to underscores for
my methods...

I've got it all working nicely now. I used Tom's sample
code as a starting point. Thanks, Tom!

The Observable pattern that itsme213 recommended doesn't
seem to fit my needs since I need multiple listeners per
emitter but maybe that's just Java think...

Anyway, here's the code I ended up using, in case anyone
else wants to do this sort of thing. (I tried defining
attr_emitter as "def self.attr_emitter" in the Emitter
module, but that didn't work. It seems like you have
to define these types of things in the Module class?)

Thanks everyone for your help!

-Paul

class Module

  def attr_emitter(*attrs)
    attrs.each do |attr|
      class_eval %{

        def #{attr}
          @#{attr}
        end

        def #{attr}=(x)
          old = @#{attr}
          @#{attr} = x
          emit(:#{attr}, old)
        end
      }
    end
  end

end

module Emitter

  def add_listener(listener)
    raise "Invalid listener" unless listener.respond_to? :property_changed
    @emitter_listeners = unless @emitter_listeners
    @emitter_listeners.push(listener)
    self
  end

  def remove_listener(listener)
    return self unless @emitter_listeners
    @emitter_listeners.delete(listener)
    self
  end

  def emit(sym, oldValue)
    return self unless @emitter_listeners
    @emitter_listeners.each { |x| x.property_changed(self, sym, oldValue) }
    self
  end

end

Observable does support multiple listeners, just FYI.

James Edward Gray II

···

On Dec 15, 2004, at 4:28 PM, Jack, Paul wrote:

The Observable pattern that itsme213 recommended doesn't
seem to fit my needs since I need multiple listeners per
emitter but maybe that's just Java think...

James Edward Gray II wrote:

The Observable pattern that itsme213 recommended doesn't
seem to fit my needs since I need multiple listeners per
emitter but maybe that's just Java think...

Observable does support multiple listeners, just FYI.

James Edward Gray II

If he's talking about standard ruby Observable, then yes it does support multiple listeners.

If he's talking about my inaptly named Observable module (shoulda been ObservableAttrs) then the answer is more subtle.

You can have multiple listeners, as long as the listeners are distinct object, rather than multiple listener clauses for one object. In fact, multiple listener clauses for an object are perfectly fine too, as long as they are listening for distinct patterns. The following example has two listeners, each with two "when" clauses:

   require 'observable'

   class Speaker
     extend Observable
     observable :foo
     def run
       self.foo = "1"
       self.foo = "2"
       self.foo = "3"
     end
   end

   class Listener
     def initialize(speaker)
       speaker.when_foo /2/ do |v|
         puts "saw a 2 in #{v.inspect}"
       end
       speaker.when_foo /\d/ do |v|
         puts "saw a digit in #{v.inspect}"
       end
       # This would override the first when_foo clause
       #speaker.when_foo /2/ do |v|
       # puts "overridden"
       #end
     end
   end

   spk = Speaker.new
   lst = [Listener.new(spk), Listener.new(spk)]

   spk.run

OUTPUT

saw a digit in "1"
saw a 2 in "2"
saw a digit in "2"
saw a 2 in "2"
saw a digit in "3"

···

On Dec 15, 2004, at 4:28 PM, Jack, Paul wrote: