Ruby Object listener?

M

Maran Chandrasekar

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,
 
7

7stud --

class MyHash < Hash
def [](key)
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
 
B

Brian Candler

Maran said:
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"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,170
Messages
2,570,925
Members
47,468
Latest member
Fannie44U3

Latest Threads

Top