# Is there a hook that is called whenever an instance variable

**URL:** <https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537>\
**Category:** Ruby\
**Created:** [November 20, 2006, 2:45pm UTC](https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537 "2006-11-20T14:45:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeremyheiler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jeremyheiler](https://www.ruby-forum.com/u/jeremyheiler)\
**Post date:** [November 20, 2006, 2:45pm UTC](https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537/1 "2006-11-20T14:45:46Z")

</div>

I’m developing an editing application with full undo/redo, so my  
objects must log all changes to a history that can be rolled backwards  
and forwards. This is just crying out for some fancy metaprogramming,  
and 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?

Regards,

Jeremy H.

---

<div class="post-metadata">

**Author:** ![jeremyheiler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jeremyheiler](https://www.ruby-forum.com/u/jeremyheiler)\
**Post date:** [November 20, 2006, 2:45pm UTC](https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537/2 "2006-11-20T14:45:54Z")

</div>

On 11/19/06, Jeremy H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’m developing an editing application with full undo/redo, so my  
> objects must log all changes to a history that can be rolled backwards  
> and forwards. This is just crying out for some fancy metaprogramming,  
> and 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?
> 
> Regards,
> 
> Jeremy H.

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

o = A.new  
o.a=[4, 8, 15, 16, 23] # =\> called a=  
o.b=42 # =\> called b=

puts o.b # just 42, without any “called b”

---

<div class="post-metadata">

**Author:** ![jeremyheiler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jeremyheiler](https://www.ruby-forum.com/u/jeremyheiler)\
**Post date:** [November 21, 2006, 1:10am UTC](https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537/3 "2006-11-21T01:10:54Z")

</div>

On 2006-11-19, Sander L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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 H.

---

<div class="post-metadata">

**Author:** ![jeremyheiler](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@jeremyheiler](https://www.ruby-forum.com/u/jeremyheiler)\
**Post date:** [November 21, 2006, 12:08pm UTC](https://www.ruby-forum.com/t/is-there-a-hook-that-is-called-whenever-an-instance-variable/76537/4 "2006-11-21T12:08:32Z")

</div>

On 11/21/06, Jeremy H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On 2006-11-19, Sander L. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > On 11/19/06, Jeremy H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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?

If you grep through the mailing list for “Observing changes in object  
state” you’ll find two different solutions to the problem - longish  
posts, so I won’t repeat them here.

Cheers,  
Max
