From: nornagon Date: 2005-07-05T15:23:48+09:00 Subject: Re: Observer patch On 7/5/05, nornagon wrote: > Hi all. > > A while ago, I was playing with some network programming, and found > that I wanted to have a class that would observe two other Observable > classes. I could have done this by sending another parameter with > notify_observers specifying which class the update came from -- but > that is, to say the least, ugly. So I came up with this patch. > (attached) > > What it does is allow you to append a paramter to add_observer. > Observable will then take that paramater and use it instead of the > default :update -- that means you can have one Observable class call > #update_class1 on your class and have the next call #update_class2. > > Originally I kept the internal list of observers as an array and kept > the method to send in a class variable, but that pollutes the > namespace further and does not allow for multiple classes observing > the same class to use different method names. So I moved the list of > observers to a hash, that each class could have its own method called. > > Without further ado, I present The Patch. Hmm, I just noticed that the patch appears as a big unreadable string of letters and numbers on ruby-talk.org, so here it is in plain text. --- observer.rb 2005-07-05 09:28:14.452114352 +1000 +++ observer-new.rb 2005-07-05 09:36:49.987741024 +1000 @@ -120,12 +120,12 @@ # Add +observer+ as an observer on this object. +observer+ will now receive # notifications. # - def add_observer(observer) - @observer_peers = [] unless defined? @observer_peers - unless observer.respond_to? :update - raise NoMethodError, "observer needs to respond to `update'" + 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.to_s}'" end - @observer_peers.push observer + @observer_peers[observer] = func end # @@ -181,9 +181,9 @@ def notify_observers(*arg) if defined? @observer_state and @observer_state if defined? @observer_peers - for i in @observer_peers.dup - i.update(*arg) - end + @observer_peers.each { |k, v| + k.send v, *arg + } end @observer_state = false end -- - nornagon