Why does `send` fail with Ruby 2.0 refinement?

为君一笑 提交于 2019-12-05 18:41:56

问题


Why does this not work?

module StringRefinement
  refine String do
    def bar
      length
    end
  end
end

using StringRefinement
"abcdefghijklmnopqrstuvwxyz".send(:bar)
#NoMethodError: undefined method 'bar' for "abcdefghijklmnopqrstuvwxyz":String

Can someone explain why send doesn't work here? And is there a way to dynamically call methods defined in a refinement? I can't seem to find a good, full explanation of how refinements work in Ruby 2.0.


回答1:


Because the specification says so:

Indirect method accesses

Any indirect method access such as Kernel#send, Kernel#method, and Kernel#respond_to? shall not honor refinements in the caller context during method lookup.




回答2:


I am tempted to say "This is by design". But again it's quite possible this design is not entirely stable. For example, the module and class scoping feature has been removed just a few months ago.

At the moment even on Ruby HEAD the only way is to use the root of all evil:

eval "puts 'abcdefghijklmnopqrstuvwxyz'.bar" # => 26

But really, this is just for the lab, right ? Do not unchain such code, kitten would die.



来源:https://stackoverflow.com/questions/15263261/why-does-send-fail-with-ruby-2-0-refinement

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!