module Observable

def add_observer(observer, func=:update)

Observable
*arg is the value passed to #notify_observers by this
receive *arg when #notify_observers is called, where
This method must return true for +observer.respond_to?+ and will

has changes.
+func+:: Symbol naming the method that will be called when this Observable
+observer+:: the object that will be notified of changes.

notifications.
Add +observer+ as an observer on this object. So that it will receive
def add_observer(observer, func=:update)
  @observer_peers = {} unless defined? @observer_peers
  unless observer.respond_to? func
    raise NoMethodError, "observer does not respond to `#{func}'"
  end
  @observer_peers[observer] = func
end

def changed(state=true)


+state+:: Boolean indicating the changed state of this Observable.

the changed +state+ is +true+.
Set the changed state of this object. Notifications will be sent only if
def changed(state=true)
  @observer_state = state
end

def changed?


#notify_observers call.
Returns true if this object's state has been changed since the last
def changed?
  if defined? @observer_state and @observer_state
    true
  else
    false
  end
end

def count_observers


Return the number of observers associated with this object.
def count_observers
  if defined? @observer_peers
    @observer_peers.size
  else
    0
  end
end

def delete_observer(observer)

+observer+:: An observer of this Observable

receive notifications.
Remove +observer+ as an observer on this object so that it will no longer
def delete_observer(observer)
  @observer_peers.delete observer if defined? @observer_peers
end

def delete_observers


Remove all observers associated with this object.
def delete_observers
  @observer_peers.clear if defined? @observer_peers
end

def notify_observers(*arg)

*arg:: Any arguments to pass to the observers.

The changed state is then set to +false+.
This will invoke the method named in #add_observer, passing *arg.

+true+.
Notify observers of a change in state *if* this object's changed state is
def notify_observers(*arg)
  if defined? @observer_state and @observer_state
    if defined? @observer_peers
      @observer_peers.each do |k, v|
        k.__send__(v, *arg)
      end
    end
    @observer_state = false
  end
end