3

我想用某种速记来表达以下内容:

stuff.map {|x| puts x}

像这样:

stuff.map {puts}

我无法弄清楚语法。有人可以告诉我如何做到这一点吗?

4

6 回答 6

6

首先:在这里使用没有意义map,因为您不是在进行映射操作,而是进行简单的副作用迭代。这正是它的each用途。使用map只会让未来的维护者(包括你自己)感到困惑。

eachmap采取一个块。您可以使用一元前缀&运算符将任何响应的对象to_proc转换为块。值得庆幸的是,Methods确实响应to_proc,因此您可以直接传递要调用的方法:

stuff.each(&method(:puts))

但是,如果stuffArray,还有一种更简单的方法,因为puts特殊情况Arrays 可以完全按照您正在做的事情。因此,您的代码 100% 等同于

puts stuff
于 2013-01-07T02:03:46.030 回答
4

既然你有一个数组,你可以写

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
于 2013-01-06T18:48:31.260 回答
3

也许你在暗示map(&:method)语法,但在puts' 的情况下这是不可能的。

在引擎盖下,Ruby 调用to_proc了这个符号。这个方法的主体是:

def to_proc
  proc { |obj, *args| obj.send(self, *args) }
end

在您的情况下, obj 是stuff并且 self 是puts

如您所知,stuff不响应该puts方法,因此您不能在当前表达式中使用符号构造。

于 2013-01-06T18:47:36.580 回答
2

虽然它已经关闭,但我建议:

stuff.map(&Kernel.method(:puts))
于 2013-01-06T18:55:26.420 回答
2

你需要一个接收器

Array#map的块格式返回一个数组,因此您仍然需要一个接收器(例如 Kernel,使用Kernel#puts)将每个元素发送到标准输出。你可以这样做:

puts [1, 2, 3].map(&:to_s)

但这肯定不会使事情变得更短或更清晰。也许你应该重新审视你真正想要完成的事情。

于 2013-01-06T18:45:15.767 回答
0

根据文档

a.map(& puts)

返回一个枚举器。您还可以执行以下操作:

puts a.map(&:to_s)

打印出每个元素。

于 2013-01-06T18:44:58.983 回答