Project

General

Profile

Actions

Feature #12079

closed

Loosening the condition for refinement

Feature #12079: Loosening the condition for refinement

Added by sawa (Tsuyoshi Sawada) over 9 years ago. Updated about 9 years ago.

Status:
Rejected
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 3 (0 open3 closed)

Has duplicate Ruby - Bug #12530: Module RefinementsRejectedshugo (Shugo Maeda)Actions
Is duplicate of Ruby - Feature #9451: Refinements and unary & (to_proc)Closedmatz (Yukihiro Matsumoto)Actions
Is duplicate of Ruby - Feature #11476: Methods defined in Refinements cannot be called via sendClosedmatz (Yukihiro Matsumoto)Actions

Updated by sawa (Tsuyoshi Sawada) over 9 years ago Actions #1 [ruby-core:73902]

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 9 years ago Actions #2 [ruby-core:73904]

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 9 years ago Actions #3 [ruby-core:75761]

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

Updated by shugo (Shugo Maeda) over 9 years ago Actions #4 [ruby-core:76126]

  • 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 9 years ago Actions #5

  • Has duplicate Bug #12530: Module Refinements added

Updated by matz (Yukihiro Matsumoto) over 9 years ago Actions #6 [ruby-core:76188]

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

Matz.

Updated by shugo (Shugo Maeda) about 9 years ago Actions #7

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

Updated by shugo (Shugo Maeda) about 9 years ago Actions #8

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

Updated by shugo (Shugo Maeda) about 9 years ago Actions #9 [ruby-core:77216]

  • Status changed from Assigned to Rejected

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

Actions

Also available in: PDF Atom