Observer patch

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.

observer-patch.diff (1.02 KB)

···

--
- nornagon

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.

···

On 7/5/05, nornagon <nornagon@gmail.com> 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.

   #
- 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

nornagon <nornagon@gmail.com> writes:

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.

I think this is a useful and sensible addition.

Whether or not you are observing multiple objects, you want your
method to have a more descriptive name than `update'.

···

--
Daniel Brockman <daniel@brockman.se>

If nobody objects to this patch, I will post it on ruby-core and try
to get it merged. :slight_smile:

I'd appreciate it if someone would check over the patch to see if it
breaks anything -- it's a pretty trivial patch, but it's better to be
safe than sorry...

···

On 7/5/05, nornagon <nornagon@gmail.com> 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.

--
- nornagon

nornagon wrote:

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.

Well, any MIME-aware MUA will be able to read it correctly. GMANE
displays it fine as well,
        nikolai

···

--
Nikolai Weibull: now available free of charge at http://bitwi.se/\!
Born in Chicago, IL USA; currently residing in Gothenburg, Sweden.
main(){printf(&linux["\021%six\012\0"],(linux)["have"]+"fun"-97);}