Kernel.y interferes with code relying on method_missing
Good day,
I have coordinate objects in protobuf which have a .y attribute defined, but rely on method_missing to trigger calls to C.
Kernel.y intercepts the message and gives me an unexpected result.
I believe other systems which also rely on method_missing like nokogiri will cause the same trouble when trying to access an arbitrary "y" property in a document.
Can we rename the "y" patch to Kernel, to something less common, please? https://github.com/ruby/psych/blob/21f051bd1ae36809449406ad2a735c295b2c31ba/lib/psych/y.rb#L5
Otherwise people who use x,y,z coordinates get adverse effects and have to implement a workaround like the following.
def y
send(:method_missing, :y)
end
Even "yy" would be better. Thank you :)
This would make sense. #y seems like to common of a name to override. Removing it today would be a breaking change though, and wouldn't be appropriate without a new major version release.
Could you workaround it by adding this shim for yourself?
def y = method_missing(:y)
Any idea who is requiring that file? It only adds the method to Kernel if something is requiring it, and Psych does not require it by default.
$ ruby -rpsych -e'y Object.new'
-e:1:in `<main>': undefined method `y' for main (NoMethodError)
y Object.new
^
I'm not thrilled with Psych adding Kernel#y (it's inherited as a legacy feature, and I'm open to a discussion about removing it), but since you have to specifically require psych/y for it to happen, it seems like that's the place to fix.
Thanks for your time. I should've added steps to reproduce in that moment, because my scenario eludes me today.
It would appear that this issue only occurs when IRB is defined.
https://github.com/ruby/psych/blob/be0ba74e5613c20f213403e15914d24944c2652d/lib/psych/core_ext.rb#L17
So I must have been either inside bundler's gem-templated bin/console (which fires up irb) or maybe some past version of RubyMine's debugger.
Found some fresh steps to reproduce:
$ irb
irb(main):001> y Object.new
(irb):1:in `<main>': undefined method `y' for main (NoMethodError)
from <internal:kernel>:187:in `loop'
[ Truncated... ]
irb(main):002> require "yaml" # or require "psych"
=> true
irb(main):003> y Object.new
--- !ruby/object {}
=> nil
I'm feeling less strong about it now, since in all likelyhood it doesn't effect anyone's live environments.
However, if anyone ever requires anything which defines ::IRB by happenstance, there could be production implications for #y.
Feel free to close.