Issue #13581 has been updated by baweaver (Brandon Weaver).


sevos (Artur Roszczyk) wrote:
> 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?

I like the idea of triple-colon as well for succinctness.

Most of the alternative in terms of succinctness would involve discussing the no-parens syntax which is likely a non-starter for obvious compatibility reasons. 

That is, unless there's a way to stop paren-free method calling in the presence of an `&` or `to_proc`:

```ruby
[1,2,3].map(&Math.sqrt)
Math.sqrt.to_proc
```

...but that feels like an excess of black magic in the parser and would likely be prone to bugs.

I really do like what Scala does with underscores:

```scala
[1,2,3].map(_ * 10)
```

...but I also understand that that would also be hugely breaking in terms of syntax as well.

Really though I think given what Ruby already does the triple-colon is the cleanest route for now.

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

* 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>