Ruby observer module

Consider the case:

  def do_stuff
    step_that_might_change_self()
    another_step_that_might_change_self()
    yet_another_step_that_might_change_self()
  end

Any of the methods called by do_stuff MIGHT change the data, but then
again they might not. do_stuff should appear as an atomic operation
from outside the object, so we don't want to call notify_observers in
all three methods. What we really want to do is do all of the steps
and then, when they are finished, notify our observers - but only if
we've actually been changed. So we write it like this:

  def do_stuff
    step_that_might_change_self()
    another_step_that_might_change_self()
    yet_another_step_that_might_change_self()
   notify_observers
  end

And then it is each step's responsibility to call #changed if and only
if they actually made a change. If a change was made by one or more
steps, our observers are notified ONCE at the end.

···

On Fri, May 23, 2008 at 2:49 PM, S2 <x@y.z> wrote:

I also have another question: why does the subject (the notifying class)
need to call "changed"? Wouldn't it be sufficient to call notify_observers?
I mean, if I call notify_observers in the Subject class, doesn't that imply
has something has changed?

--
Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

Maybe it's because there might be another event beside changed ?

///ark

···

On May 23, 2008, at 12:34 PM, S2 wrote:

Yes, in this case it makes sense, but think of this:

def do_stuff
   @mint = 'blue'
   notify_observers
end

Nice and clean, isn't it?
If I implement something like you sad, wouldn't it make more sense to create
a @changed variable in the Subject class, and call notify_observers only if
@changed == true instead of forcing a call to changed every time?

Avdi Grimm wrote:

And then it is each step's responsibility to call #changed if and only
if they actually made a change. If a change was made by one or more
steps, our observers are notified ONCE at the end.

Yes, in this case it makes sense, but think of this:

  def do_stuff
    @mint = 'blue'
    notify_observers
  end

Nice and clean, isn't it?
If I implement something like you sad, wouldn't it make more sense to create
a @changed variable in the Subject class, and call notify_observers only if
@changed == true instead of forcing a call to changed every time?

What you describe is exactly what happens if you use #changed and #notify_observers the way they are intended. Look into the implementation of #changed and #notify_observers.

And for simple cases nothing stops you from doing something like this:

def force_notify
   changed
   notify_observers
end

Well, it's perfectly fine to me how it is implemented now, it just looks a
bit ugly to me, but maybe it's just me (that call to changed does not
really add anything, and the functionality it provides is trivial (if it is
intended like you explained it)).

What's wrong with having a method with trivial implementation? Note, that the method has the added advantage to be overridable and changeable - so you are a lot more flexible.

Kind regards

  robert

···

On 23.05.2008 21:30, S2 wrote: