# Ruby Object listener?

**URL:** <https://www.ruby-forum.com/t/ruby-object-listener/172358>\
**Category:** Ruby\
**Created:** [July 20, 2009, 7:44am UTC](https://www.ruby-forum.com/t/ruby-object-listener/172358 "2009-07-20T07:44:27Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![manimaran](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8e7dd6/32.png) [@manimaran](https://www.ruby-forum.com/u/manimaran)\
**Post date:** [July 20, 2009, 7:44am UTC](https://www.ruby-forum.com/t/ruby-object-listener/172358/1 "2009-07-20T07:44:27Z")

</div>

Dear folks,  
I have a Hash Object. If any thing added, removed or modified in that  
Hash. I want to trigger a operation. How could I do that?

Thanks,

---

<div class="post-metadata">

**Author:** ![manimaran](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8e7dd6/32.png) [@manimaran](https://www.ruby-forum.com/u/manimaran)\
**Post date:** [July 20, 2009, 8:52am UTC](https://www.ruby-forum.com/t/ruby-object-listener/172358/2 "2009-07-20T08:52:36Z")

</div>

class MyHash \< Hash  
def   
notify  
super  
end

def []=(key, val)  
notify  
super  
end

def notify  
puts “something happened”  
end

end

h = MyHash[“a”, 10, “b”, 20]

h[“c”] = 30  
val = h[“c”]

–output:–  
something happened  
something happened

---

<div class="post-metadata">

**Author:** ![manimaran](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/8e7dd6/32.png) [@manimaran](https://www.ruby-forum.com/u/manimaran)\
**Post date:** [July 20, 2009, 5:06pm UTC](https://www.ruby-forum.com/t/ruby-object-listener/172358/3 "2009-07-20T17:06:57Z")

</div>

Maran Chandrasekar wrote:

> Dear folks,  
> I have a Hash Object. If any thing added, removed or modified in that  
> Hash. I want to trigger a operation. How could I do that?

You cannot detect the general case of anything “modified” in that Hash,  
unless you build objects which know they are modified and know who to  
notify. e.g.

a = {1=\>“foo”, 2=\>“bar”}

a[2].replace(“baz”)

The second operation is a method call to the String object which mutates  
that String. The Hash never sees it, and is still pointing to the same  
object both before and after the call. Furthermore, multiple hashes  
could be pointing to the same object. A standard String has no idea  
which Hash(es) might contain it.

If you are only interested in modifications to the Hash itself, not the  
objects it contains, then you can intercept all calls which might modify  
it (perhaps using delegate.rb). Note that this includes a large number  
of methods, some of which take blocks, like delete\_if.

If you want to notify multiple clients, then have a look at observer.rb  
in the standard library.

If you don’t need immediate notification, and are prepared to poll  
occasionally, then you could consider doing a Marshal.dump of the Hash,  
taking an SHA1 digest of that, and seeing if the digest is the same or  
different.

> > require ‘digest/sha1’  
> > =\> true
> 
> > a = {1=\>“foo”, 2=\>“bar”}  
> > =\> {1=\>“foo”, 2=\>“bar”}
> 
> > Digest::SHA1.hexdigest(Marshal.dump(a))  
> > =\> “d28ca1b04097274124675d63b227ecc15c71a0c5”
> 
> > Digest::SHA1.hexdigest(Marshal.dump(a))  
> > =\> “d28ca1b04097274124675d63b227ecc15c71a0c5”
> 
> > a[2].replace(“baz”)  
> > =\> “baz”
> 
> > Digest::SHA1.hexdigest(Marshal.dump(a))  
> > =\> “c6661b1010def28517ef5da33a9e540f324bff5c”
> 
> >
