On 2006-11-19, Sander Land <sander.land / gmail.com> wrote:
> On 11/19/06, Jeremy Henty <jeremy / chaos.org.uk> wrote:
>> ... it would be really neat if I could insert some code that is
>> called whenever an object assigns an instance variable.  Is there
>> anything like that?
>
> I'm not aware of any hooks for instance variables, but as long as
> you're setting everything using setter methods or attr_accessor you
> can just hook into all methods ending in a "=".
>
> class A
>   attr_accessor :a, :b
>   instance_methods(false).each{|m|
>     alias_method "orig_#{m}",m
>     define_method(m){|*args|
>       puts "called #{m}"
>       send("orig_#{m}",*args)
>     } if m[-1] == ?=
>   }
> end

Nice!  My mind boggled a little over "if m[-1] == ?=" but I get it
now.  I guess the industrial strength solution would be a mixin that
when included into Foo: (a) hooks all existing Foo#*= methods as you
do above, (b) defines Foo#method_added to hook all Foo#*= methods that
are subsequently def'ed, (c) defines Foo#method_missing to handle
Foo#*= methods similarly.

Of course this assumes only *= methods change the object, which is not
true of Hash, Array etc.  I guess what I *really* want is an
Object#object_changed hook.

Regards, 

Jeremy Henty