Issue #13581 has been updated by sevos (Artur Roszczyk).


After a while I am becoming a bigger fan of the triple colon operator. We could implement a class MethodSelector for handling the logic and the operator would be expected to return an instance of the class:

~~~ruby
class MethodSelector
  def initialize(b, receiver, m)
    @binding = b
    @receiver = receiver
    @method = m
  end

  def call(*args, **kwargs, &block)
    # ...
  end

  def to_proc
    if @binding.eval("self") == @receiver
      proc do |*args, **kwargs, &block|
        if kwargs.empty?
          @receiver.send(@method, *args, &block)
        else
          @receiver.send(@method, *args, **kwargs, &block)
        end
      end
    else
      proc do |*args, **kwargs, &block|
        if kwargs.empty?
          @receiver.public_send(@method, *args, &block)
        else
          @receiver.public_send(@method, *args, **kwargs, &block)
        end
      end
    end
  end
end

# Instead of MS() method we should implement ::: operator (taking two argiments):
# receiver:::method expands to MS(binding, receiver, method)
class Object
  def MS(b, receiver, m)
    MethodSelector.new(b, receiver, m)
  end
end

# Example usage
> MS(binding, Kernel, :puts) # the triple colon operator should expand current binding by default
=> #<MethodSelector:0x007fdba89bd0a8 @binding=#<Binding:0x007fdba89bd0d0>, @receiver=Kernel, @method=:puts>
> [1,2,3].each(&MS(binding, Kernel, :puts))
1
2
3
=> nil
~~~

There is still the question how to enable meta-programming with triple colon operator.
Imagine the situation when the method name is dynamic. How to distinguish it from the symbol?


~~~ruby
method = :puts

Kernel:::puts
Kernel:::method
~~~
The only logical solution to me is the presence of the fourth colon for the symbol:

~~~ruby
method = :puts

Kernel::::puts # evaluates as Kernel:::(:puts)
Kernel:::method # evaluates as Kernel:::(method)
~~~

What are your thoughts?

----------------------------------------
Feature #13581: Syntax sugar for method reference
https://bugs.ruby-lang.org/issues/13581#change-70223

* Author: americodls (Americo Duarte)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
Some another programming languages (even Java, in version 8) has a cool way to refer a method as a reference.

I wrote some examples here: https://gist.github.com/americodls/20981b2864d166eee8d231904303f24b

I miss this thing in ruby.

I would thinking if is possible some like this:

~~~
roots = [1, 4, 9].map &Math.method(:sqrt)
~~~

Could be like this:

~~~
roots = [1, 4, 9].map Math->method
~~~

What do you guys thinking about it?



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>