Feature #12079
closedLoosening the condition for refinement
Description
There are a few non-standard ways of calling a method that cannot be used when the relevant method is a refined method:
- a symbol used with
&
as a block via symbol to proc - a symbol used with
send
or__send__
For example, the following will fail:
module Foo
refine String
def baz; end
end
end
using Foo
["a", "b", "c"].map(&:baz) # => undefined method error
"a".send(:baz) # => undefined method error
I would like to propose to loosen the condition for refinement so that as long as the relevant construction (such as the use of &
to provoke Symbol#to_proc
or calling of send
or __send__
) is within the valid scope of refinement, allow the call to the relevant methods.
Updated by sawa (Tsuyoshi Sawada) over 8 years ago
To the list of relevant constructions, I would also like to add inject
when it takes a symbol argument.
module Foo
refine String do
def baz a, b; a + b * 2 end
end
end
using Foo
["x", "y", "z"].inject(:baz) # => undefined method error
["x", "y", "z"].inject("", :baz) # => undefined method error
So my generalization for the target of my proposal is: Ruby core methods/constructions in which a(nother) method is called in the form of a symbol or a string. There may be a few more of them that I have missed.
Updated by sawa (Tsuyoshi Sawada) over 8 years ago
There is a point that needs to be made clear regarding this proposal: whether the symbol or string used in the construction has to be a literal. I think there would be use cases where the symbol/string is expressed as a more complex expression:
module Foo
refine String do
def baz; end
end
end
def a
case some_expression
when "x" then :baz
when "y" then :bar
end
end
using Foo
["a", "b", "c"].map(&(some_condition ? :baz : :bar))
"a".__send__("BAZ".downcase)
"a".send(a)
In order for the proposal to be useful, I think the relevant symbol/string should not be restricted to literals. Furthermore, the location where the expression is expanded to a symbol/string should not matter; solely the location of &
, __send__
, or send
, etc. should matter. In above, while send
is within the scope of refinement for String#baz
, a
, which can be possibly expanded to :baz
, is expanded outside of the scope of refinement. In such cases too, I think the refinement should be effective.
Updated by hsbt (Hiroshi SHIBATA) over 8 years ago
- Status changed from Open to Assigned
- Assignee set to shugo (Shugo Maeda)
Updated by shugo (Shugo Maeda) over 8 years ago
- Assignee changed from shugo (Shugo Maeda) to matz (Yukihiro Matsumoto)
I would like to propose to loosen the condition for refinement so that as long as the relevant construction (such as the use of & to provoke Symbol#to_proc or calling of send or send) is within the valid scope of refinement, allow the call to the relevant methods.
What do you think, Matz?
Updated by shugo (Shugo Maeda) over 8 years ago
- Has duplicate Bug #12530: Module Refinements added
Updated by matz (Yukihiro Matsumoto) over 8 years ago
I agree that would be nicer to users. My concern is performance penalty.
Matz.
Updated by shugo (Shugo Maeda) about 8 years ago
- Is duplicate of Feature #9451: Refinements and unary & (to_proc) added
Updated by shugo (Shugo Maeda) about 8 years ago
- Is duplicate of Feature #11476: Methods defined in Refinements cannot be called via send added
Updated by shugo (Shugo Maeda) about 8 years ago
- Status changed from Assigned to Rejected