Project

General

Profile

Feature #12079

Loosening the condition for refinement

Added by sawa (Tsuyoshi Sawada) over 3 years ago. Updated almost 3 years ago.

Status:
Rejected
Priority:
Normal
Target version:
-
[ruby-core:73845]

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.


Related issues

Has duplicate Ruby trunk - Bug #12530: Module RefinementsRejectedActions
Is duplicate of Ruby trunk - Feature #9451: Refinements and unary & (to_proc)ClosedActions
Is duplicate of Ruby trunk - Feature #11476: Methods defined in Refinements cannot be called via sendClosedActions

History

Updated by sawa (Tsuyoshi Sawada) over 3 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 3 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) about 3 years ago

  • Assignee set to shugo (Shugo Maeda)
  • Status changed from Open to Assigned

Updated by shugo (Shugo Maeda) about 3 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?

#5

Updated by shugo (Shugo Maeda) almost 3 years ago

  • Has duplicate Bug #12530: Module Refinements added

Updated by matz (Yukihiro Matsumoto) almost 3 years ago

I agree that would be nicer to users. My concern is performance penalty.

Matz.

#7

Updated by shugo (Shugo Maeda) almost 3 years ago

  • Is duplicate of Feature #9451: Refinements and unary & (to_proc) added
#8

Updated by shugo (Shugo Maeda) almost 3 years ago

  • Is duplicate of Feature #11476: Methods defined in Refinements cannot be called via send added

Updated by shugo (Shugo Maeda) almost 3 years ago

  • Status changed from Assigned to Rejected

This issue will be addressed by #9451 and #11476.

Also available in: Atom PDF