我想用某种速记来表达以下内容:
stuff.map {|x| puts x}
像这样:
stuff.map {puts}
我无法弄清楚语法。有人可以告诉我如何做到这一点吗?
首先:在这里使用没有意义map
,因为您不是在进行映射操作,而是进行简单的副作用迭代。这正是它的each
用途。使用map
只会让未来的维护者(包括你自己)感到困惑。
each
并map
采取一个块。您可以使用一元前缀&
运算符将任何响应的对象to_proc
转换为块。值得庆幸的是,Method
s确实响应to_proc
,因此您可以直接传递要调用的方法:
stuff.each(&method(:puts))
但是,如果stuff
是Array
,还有一种更简单的方法,因为puts
特殊情况Array
s 可以完全按照您正在做的事情。因此,您的代码 100% 等同于
puts stuff
既然你有一个数组,你可以写
puts stuff
但是,一般来说,您可以向 String 或 Object 添加一个方法,然后可以直接将其传递给一个方法,Enumerable.
因为Symbol
有一个to_proc
方法,您可以在不需要块的情况下调用该方法。
class Object; def myputs; puts self; nil; end; end
stuff.each &:myputs # or, even better, ...
stuff.myputs
也许你在暗示map(&:method)
语法,但在puts
' 的情况下这是不可能的。
在引擎盖下,Ruby 调用to_proc
了这个符号。这个方法的主体是:
def to_proc
proc { |obj, *args| obj.send(self, *args) }
end
在您的情况下, obj 是stuff
并且 self 是puts
。
如您所知,stuff
不响应该puts
方法,因此您不能在当前表达式中使用符号构造。
虽然它已经关闭,但我建议:
stuff.map(&Kernel.method(:puts))
Array#map的块格式返回一个数组,因此您仍然需要一个接收器(例如 Kernel,使用Kernel#puts)将每个元素发送到标准输出。你可以这样做:
puts [1, 2, 3].map(&:to_s)
但这肯定不会使事情变得更短或更清晰。也许你应该重新审视你真正想要完成的事情。