OpenStruct.new saves an attribute but does not retrieve it

After creating a new Ruby OpenStruct object, I can store the attributes but not retrieve them (I get an empty string and returns nil instead):

 obj = OpenStruct.new # => #<OpenStruct> obj.x = 10 obj.y = 20 obj # => #<OpenStruct x=10, y=20> obj.x # => 10 obj.y # # => nil 

If I try to save other properties with different names, everything works as expected. This problem only occurs when I store a property named y . I am using the following version:

ruby 1.9.2p320 (2012-04-20 revision 35421) [i686-linux]

Does anyone have any idea what is going on?

+4
source share
1 answer

Something pulls Psych somewhere for the YAML stuff. Psychic patches Kernel add psych_y method, which will be an alias of y . So everything has a y method:

 > o = OpenStruct.new > o.method(:y) => #<Method: OpenStruct(Kernel)#psych_y> 

AFAIK, OpenStruct uses method_missing and an internal hash to create accessors and mutators; but y already exists from this "friendly" patch to the kernel, so OpenStruct magic can't handle the y method because Psych magic is on the way. The mutator, y= , is excellent, so you can safely oy = 11 and see your 11 inside o .

You can remove y like this:

 > o = OpenStruct.new > o.class_eval('undef_method :y') > oy = 11 > oy => 11 

You can probably remove the method from Kernel and hope that nothing depends on this stupid alias y :

 > Kernel.send(:undef_method, :y) > o = OpenStruct.new > oy = 11 > oy => 11 

Or you can simply remove it from OpenStruct :

 > OpenStruct.send(:undef_method, :y) > o = OpenStruct.new > oy = 11 > oy => 11 

This is why many people do not like the patch of monkeys, especially the monkey correcting something fundamental, like Kernel .

+5
source

Source: https://habr.com/ru/post/1443977/


All Articles