------art_57465_28066223.1221935452603
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Sat, Sep 20, 2008 at 1:10 PM, Carlos Ortega <caof2005 / yahoo.com> wrote:

> Hi folks.
> I tried to reproduce a Mixin example that is include in the Pick Axe
> book, here's the code:
>
> module Observable
>  def observers
>       @observer_list || ]
>  end
>
>  def add_observer( obj )
>   # ----?????
>    observers << obj
>  end
>
>  def print_observers
>    @observer_list.each{ |i| puts i  }
>  end
>
> end
>
> def notify_observers
>    # ----?????
>    observers.each {|o| o.update }
> end
>
> It works great however while reviewing the code  I noticed a couple of
> situations that I really don't understand:
> 1)  Is it possible to invoke a method with a "<<" notation ?
>
> What I mean is that inside the "add_observer" method I'm calling
> observers using << instead of parenthesis:
>
>  def add_observer( obj )
>    observers << obj
>  end


observers is a method defined in the Observable module.  I'll address <<
after...


On the other side while reviewing the "observers" method, I noticed that
> there is no parameter in its definition:
>  def observers
>       @observer_list || ]
>  end


> Is this valid ? ( I suppose it is because it works ), but how does this
> works ?


Sure it is valid there's no rule that a method must take a parameter, lots
don't.

 So what is happening in the add_observer method is that the observers
method is invoked, it uses a lazy initialization pattern to initialize and
instance variable to an empty array if necessary, and returns that instance
variable.

Note that this is interpreted the same as if it had been:

def add_observer(obj)
    self.observers << obj
end

the self is implied.

Then the << message is sent to the result of the observers method with obj
as the parameter.

>
>
> 2) Same situation happens in the "notify_observers" method, in it I can
> invoke "observers.each" although it is not defined anywhere. Why can I
> do that?


Same thing each is being sent to the object resulting from the observers
method.

Now lets look at your usage of the module:

> class TelescopeScheduler
> include Observable

> def initialize
>   @observer_list   ]
> end

This is unnecessary, since @observer_list is initialized by the module
method when needed.

> def add_viewer( viewer )
>   @observer_list << viewer
> end

This isn't really using the module.  The whole TelescopeScheduler class, as
written, can be just:

class TelescopeScheduler
    include Observable

    alias_method :add_viewer, :add_observer
end


-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

------art_57465_28066223.1221935452603--