Because the specification says so:
Indirect method accesses
Any indirect method access such as
Kernel#send
,Kernel#method
, andKernel#respond_to?
shall not honor refinements in the caller context during method lookup.
Pregunta
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.
Solución
Because the specification says so:
Indirect method accesses
Any indirect method access such as
Kernel#send
,Kernel#method
, andKernel#respond_to?
shall not honor refinements in the caller context during method lookup.
Otros consejos
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.