On Wed, Oct 16, 2002 at 04:10:14PM +0000, ahoward wrote:
> 
> > > > Is there a way to hook on invocation of *any* instance method of
> > > > an
> > > > object?
> ...
> [snip]
> ...
> >
> > Code follows:
> >
> > module Observable
> ...
> [snip]
> ...
> > theproxy.another
> 
> 
> that seems pretty complicated - it seems like what is needed is a
> specialization of a class, espcially since only the assignment methods
> need
> overridden.  isn't this *the* job of inheritence?  eg:

In fact this could be meaningful w/ any method that changes the state
of an object, assignment or not.

> 
> 
> def assignment_hook(*args)
>   re = /`([^']+)'/
>   m = re.match caller(1)[0]
>   m or raise 'FAILED TO LOOKUP METHOD NAME'
>   methodname = m[1]
> 
>   # notify observer here...
>   puts "hook for #{methodname}(#{args.join ','}) called..."
> end
> 
> class Original
>   def foo=(*args)
>     # do something
>   end
> end
> 
> class Hooked < Original
>   def foo=(*args)
>     assignment_hook *args
>     super *args
>   end
> end
> 
> 
> h = Hooked.new
> h.foo= 0,1,2	# --> hook for foo=(0,1,2) called...
> 
> 
> simple : yes
> fast   : yes
> safe   : yes
> typing : yes

Yes, but you have to redefine all the methods needing some kind of
"write barrier". The way I showed before, the BarrierKeeper is in fact a
proxy which decides whether a method call should be forwarded or not;
and it is easily mixed with the Observer pattern.

What I don't like about inheritance is having to type 
 def method(*args)
	hook(*args)
	super *args
 end
which is of course more of a matter of taste. And then again, it would be
possible to create something like
   set_barrier :method_name, proc { |method, args| ... }
which could work either via inheritance or delegation.

Delegation gives you more freedom, for a BarrierKeeper could potentially
take care of different objects during runtime, even those of an
unknown class! If you use inheritance, you end up having to know the
class of the object _or_ using lots of singleton methods. And you'd have
to use the evil eval :-)

Guess it's just another case of object vs class design pattern...

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

I once witnessed a long-winded, month-long flamewar over the use of
mice vs. trackballs... It was very silly.
	-- Matt Welsh