From: cben@... Date: 2018-02-12T23:54:41+00:00 Subject: [ruby-core:85513] [CommonRuby Feature#13581] Syntax sugar for method reference 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: