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.