Closed SaltwaterC closed 8 years ago
Interesting bug! I have a root cause analysis. The cause is due to the different code paths of send
vs public_send
and the opportunistic defining of methods on an ROS object does to try and better mimic OpenStruct's behavior in Ruby 2.3.0+.
First:
def [](name)
send name
end
This performs a #send(name)
instead of #public_send(name)
. #send
checks all public, protected, and private methods for an object. Before you call ros.test
, There already is a private #test
method on the object, pulled in by Kernel
. When you call []
, the send(:test)
tries to call this test
method, which has an arity of 2..3
.
When you call ros.test
, #test
is not a public method on the object. This triggers #method_missing
, which eventually declares a new public method called test
on the object's eigenclass, masking Kernel#test
. After this point, #[]
calls this method, which behaves as desired.
I'll take a quick look into fixing this.
@SaltwaterC I just pushed out version 1.0.1 to rubygems. Let me know if you have any other problems.
I only hit the bug as I was looping over an array to supply the keys to read from a ROS which coincidentally has a "test" value. Normally I use the method call style (i.e the whole purpose for using ROS in the first place).
Thank you for the explanation. It would have taken me a lot of time to piece all this info as I'm relatively new at Ruby. This also explains the issues that I was having with methods that were magically appearing in OpenStruct/RecursiveOpenStruct objects after including modules which define methods. The explanation being that the inclusion of a module in the global scope attaches those module methods to every object unless they are declared in module_functions. Leaving this here for future reference.
Thanks for taking care of this. I'll let you know if 1.0.1 is breaking in unexpected ways.
Hi.
Crashes in flames with:
I've left ros.test method call in there as uncommenting that line auto-magically fixes the code and it outputs the expected:
This issue appeared with 1.0.0 while 0.6.5 works properly. I still don't know what's so special about "test" as key as this is the only way I could reproduce the bug.
Cheers!