简体   繁体   中英

How can I spy on the `[]=` method in Ruby hash?

I have a hash. One of these keys is daily_budget . After some process, daily_budget has been changed while all other keys' values have not. Either the hash's value for that key changed, or I'm cloning the hash and setting that value on the cloned hash.

I want to spy on the Hash#[]= method to figure out where this happens. I'd monkey patch it, watch for a key named daily_budget , and dump a stack trace whenever it is set.

I was trying to use a code like this:

module HashPatches
  def []=(key, value)
    puts ">>>> hey! I got here!"
    super(key, value)
  end
end

Hash.send(:include, HashPatches)

It seems like this change is ignored, while other patches on Hash are working. Did I do something wrong?

I also tried using set_trace_func to trace calls to the hash with this code,

set_trace_func proc { |event, file, line, id, binding, classname|
  if file =~ /\/my_project_name\//
    puts ">>>> #{id}"
    puts ">>>> #{classname}"
    puts ">>>> #{event}"
    puts ">>>> #{file}"
    puts ">>>> #{line}"
  end
}

but :[]= isn't traced. I'd removed the monkey patch. I couldn't get usages of :[]= to appear in this output.

Is there any way to spy changes to hashes so I can track down where this key's value is changed?

Hash.send(:include, HashPatches) only makes your HashPatches#[]= to be called when (the original) Hash#[]= is not available, which is not the case. Also, super in your HashPatches#[]= definition will not work since the superclass Object of your HashPatches does not have []= .

To give precedence to your HashPatches#[]= over the original Hash#[]= , you need to do:

Hash.prepend(HashPatches)

You can to monkey patch the Hash class itself. Put this inside the module / class definition,

class Hash
  def []=(arg)
    # do your magic here with a debugger or pry
  end 
end

Edit: This way is obsolete, but leaving for reference.

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