A flexible Ruby Observable module I was learning a bit about about observers. Ruby has an Observable module, but I decided to make my own with a few tweaks.

The first important feature is that this module calls one or more observer methods when the observed object's state is changed. When you add an observer, you also have to specify the method that will be called (by using a symbol). You can add the same observer again specifying yet another method (so if you add an observer twice (two different methods), when the object's state changes, both methods will be called).

Ruby's Observable module seems to call the #update method on the observer. I prefer to choose the method to be called, so I did that change.

The freedom to associate multiple methods to the same observer (so it is called multiple times per state change) is something I'm unsure if it is useful in any way, though. What do you think about that?

The second important feature is the ability to choose which instance variables (using symbols) will be passed to the observer when it is notified of a state change. This way, when the observer is notified, it won't have to manually read the object's instance variables, since such variables will be passed as arguments to its method.

module Observable

  def add_observer(observer,method,*instance_variables)
    @observers ||= {}
    @observers[observer] ||= []
    entry = [method,instance_variables]
    @observers[observer] &lt;&lt; entry unless @observers[observer].include?(entry)
  end

  def remove_observer(observer)
    return unless @observers
    @observers.delete(observer)
  end

  def state_changed
    return unless @observers
    @observers.each do |observer,entries|
      entries.each do |entry|
        variables = []
        entry[1].each do |symbol|
          variables &lt;&lt; instance_variable_get("@#{symbol}")
        end
        observer.send(entry[0],*variables)
      end
    end
  end

  def count_observers
    return @observers.size
  end

  alias_method :changed , :state_changed

end


Example:

observableObject.add_observer(self,:somethingChanged,:instanceVar1,:instanceVar2)


When observableObject's state changes, self's method #somethingChanged will be called. And two instance variables from observableObject (instanceVar1 and instanceVar2) will be passed to the method.

What do you think of this implementation? I like the fact that it seems to be more flexible (being able to choose which method to be called and, optionally, what instance variables to pass).
A few notes on making this look more like idiomatic Ruby:


There's no need to use return unless @observers in every method. You initialize @observers to a known value, which will never be falsy; there is no harm at all in assuming it will still be set later.
Any time you initialize an empty array, iterate a collection and (for each item) append something to the array, you're missing out on a map.

Instead of this...

variables = []
entry[1].each do |symbol|
  variables &lt;&lt; instance_variable_get("@#{symbol}")
end
observer.send(entry[0],*variables)


...use this:

variables = entry[1].map { |symbol| instance_variable_get("@#{symbol}") }
observer.send(entry[0],*variables)

The last statement in a method is the return value; get rid of your explicit returns:

def count_observers
  @observers.size
end