From: keystonelemur@... Date: 2018-04-23T07:00:13+00:00 Subject: [ruby-core:86653] [CommonRuby Feature#13581] Syntax sugar for method reference 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 > => #, @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: