Issue #13581 has been updated by cben (Beni Cherniavsky-Paskin).


A non-syntax idea: could `Math.method.sqrt` look significantly nicer than `Math.method(:sqrt)`?
That is, .method without args would return a magic object that for any message returns the bound method of that name.

~~~ruby
[1, 4, 9].map(&Math.method.sqrt).each(&method.puts)
[1, 4, 9].map(&Math.method(:sqrt)).each(&method(:puts))
[1, 4, 9].map{|*a| Math.sqrt(*a)}.each{|*a| puts(*a)}
~~~

Naive implementation (some names don't work, eg. `Math.method.method_missing`, and doesn't take visibility and refinements into account):

~~~ruby
class Methods < BasicObject
  def initialize(obj)
    @obj = obj
  end
  def method_missing(name)
    @obj.method(name)
  end
  def responds_to_missing?(name)
    true
  end
end

module MethodWithoutArgs
  def method(*args)
    if args.empty?
      Methods.new(self)
    else
      super
    end
  end
end
Object.prepend(MethodWithoutArgs)

[14] pry(main)> [1, 4, 9].map(&Math.method.sqrt).each(&method.puts)
1.0
2.0
3.0
=> [1.0, 2.0, 3.0]
~~~

BTW, what about refinements?  Is .method(:foo) ignorant about them?  A benefit of a real syntax might be that it could "see" methods from lexically active refinements.

As for syntax, I'm wondering if something *postfix* might work.  The reason I say this is I'm thinking of both &: and this as shorthands for writing out a block.
`&:` can be read locally, it roughly "stands for" `|x| x.` :

~~~ruby
[1, 2, 3].map{|x| x.to_s}
[1, 2, 3].map(&:to_s)
~~~

And with a bound method, we want to elide the argument declaration, plus the call that comes *after* the receiver.message:

~~~ruby
[1, 4, 9].map{|*a| Math.sqrt(*a)}.each{|*a| puts(*a)}
[1, 4, 9].map(&Math.sqrt:).each(&puts:)  # half baked idea
[1, 4, 9].map(Math.sqrt&).each(puts&)    # quarter baked
~~~

OK, actually there is a more generic feature I'd love much more than a syntax for bound methods: implicit notation for block arg:

~~~ruby
[1, 2, 3].map{|x| x.to_s}
[1, 2, 3].map{_.to_s}

[1, 4, 9].map{|x| Math.sqrt(x)}.each{|x| puts(x)}
[1, 4, 9].map{Math.sqrt(_)}.each{puts(_)}

[1, 2, 3].map{|x| 1/x}
[1, 2, 3].map{1/_}
~~~
(I don't think `_` is possible, just an example)

The part I love most about this is that `{}` does *not* become `(&...)`!
This doesn't easily handle multiple args, like bound methods do, but I think one arg is sweet spot for such shorthand anyway.

- I've tried prototyping this once by defining `Kernel._` that would look in caller frame, but didn't find any way to access arg in a block that didn't declare any |args|.


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

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