fields
fields

Reputation: 4653

How can I override the []= method when subclassing a Ruby hash?

I have a class that extends Hash, and I want to track when a hash key is modified.

What's the right syntax to override the [key]= syntactic method to accomplish this? I want to insert my code, then call the parent method.

Is this possible with the C methods? I see from the docs that the underlying method is

rb_hash_aset(VALUE hash, VALUE key, VALUE val)

How does that get assigned to the bracket syntax?

Upvotes: 4

Views: 5760

Answers (3)

megas
megas

Reputation: 21791

I think using set_trace_func is more general solution

class MyHash < Hash
  def initialize
    super
  end

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

set_trace_func proc { |event, file, line, id, binding, classname|
  printf "%10s %8s\n", id, classname if classname == MyHash
}

h = MyHash.new
h[:t] = 't'

#=>
initialize   MyHash
initialize   MyHash
initialize   MyHash
       []=   MyHash
       []=   MyHash
       []=   MyHash

Upvotes: 3

jobby
jobby

Reputation: 171

The method signature is def []=(key, val), and super to call the parent method. Here's a full example:

class MyHash < Hash
  def []=(key,val)
    printf("key: %s, val: %s\n", key, val)
    super(key,val)
  end
end

x = MyHash.new

x['a'] = 'hello'
x['b'] = 'world'

p x

Upvotes: 7

Alex D
Alex D

Reputation: 30465

class MyHash < Hash
  def []=(key,value)
    super
  end
end

Upvotes: 2

Related Questions