简体   繁体   中英

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?

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

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
class MyHash < Hash
  def []=(key,value)
    super
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM