如何使用`:rand`作为map / collect的一元方法?

时间:2016-09-22 15:41:49

标签: ruby

我想要一个包含滚动10个骰子的结果的矢量(比方说)。我可以这样做:

([6]*10).map{|x|rand(x)}

但这给了我一个错误数量的论点"错误:

([6]*10).map(:rand)

是否有一种无点的方法可以将rand的单参数版本传递给map

3 个答案:

答案 0 :(得分:6)

这将有效:

([6]*10).map(&method(:rand))

这不是:

([6]*10).map(&:rand)

Symbol#to_proc(大致)实现如下:

class Symbol
  def to_proc
    -> *args { args.first.public_send(self, *args.drop(1)) }
  end
end

换句话说,它将第一个参数作为接收者,将其他参数作为Symbol命名的方法的参数。所以,在你的情况下,它正在调用

6.rand

一遍又一遍。

这种"""因为6IntegerIntegerObject的间接子类,它在Kernel中混合,定义rand。但! randprivate,这意味着只能在没有明确接收者的情况下调用它。此外,您没有传递任何参数,因此即使它是public,您也会得到rand没有参数的行为,这是0 {0}之间的Float和1。

Method#to_proc传递方法的所有参数(毕竟它已经有接收器绑定),所以在这种情况下,它会调用

self.rand(6)

一遍又一遍。这当然有效,因为selfObjectObject包含KernelrandKernel中定义。

这也不会起作用:

([6]*10).map(:rand)

由于map没有任何参数的简单原因,但你传递的是参数。

答案 1 :(得分:3)

你可以写:

([6]*10).map(&method(:rand))

答案 2 :(得分:0)

这是写作的简洁方法:

10.times.map { rand(6) }

以这种方式编写可以更容易地查看传递给rand的参数。