我想要一個包含滾動10個骰子(例如)的結果的向量。我可以這樣做:如何使用`:rand`作爲map/collect的一元方法?
([6]*10).map{|x|rand(x)}
但是,這給了我一個「錯誤的參數數目」錯誤:
([6]*10).map(:rand)
有一個免費的點對點方式的rand
的一個參數版本傳遞給map
?
我想要一個包含滾動10個骰子(例如)的結果的向量。我可以這樣做:如何使用`:rand`作爲map/collect的一元方法?
([6]*10).map{|x|rand(x)}
但是,這給了我一個「錯誤的參數數目」錯誤:
([6]*10).map(:rand)
有一個免費的點對點方式的rand
的一個參數版本傳遞給map
?
這將工作:
([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
一遍又一遍。
這「種」的作品,因爲6
是Integer
,Integer
是Object
間接子類,它融合在Kernel
,它定義rand
。但! rand
是private
,這意味着它只能在沒有明確接收者的情況下被調用。此外,你不傳遞任何參數,因此即使它是public
,你會得到的rand
不帶參數的行爲,這是該方法的Float
0和1之間
而Method#to_proc
傳遞所有參數(它畢竟已經有了它的接收器),所以在這種情況下,它將一次又一次地呼叫
self.rand(6)
。當然可以工作,因爲self
是Object
,Object
包括Kernel
,而rand
定義在Kernel
中。原因很簡單,
([6]*10).map(:rand)
是map
沒有任何參數,但你傳遞一個參數:
這不會正常工作。
你可以寫:
([6]*10).map(&method(:rand))
這將是乾淨的方式來寫它:
10.times.map { rand(6) }
寫作這種方式可以更容易地看到被傳遞到rand
什麼說法。
是的,謝謝,但我意識到這一點。在實際應用中,並不是所有的骰子都有相同數量的邊,所以我真的需要將'rand'映射到一個矢量上。不過,我不想在這個問題上討論這個問題。 – rici
太好了,謝謝。我不應該在一個我沒有足夠信息的地方跳下一個結論,因爲我經常對其他人說:-把我說得對,對我來說似乎有點笨拙,但是每種語言都有自己的成語 – rici
技術上在OP的情況下,它不會調用任何東西,因爲OP只是將一個符號傳遞給'map','map'不接受任何其他參數而不是一個塊,用符號處理'&:rand', 「私人方法'蘭特'6叫:Fixnum」 – engineersmnky
@engineersmnky:啊,你是對的,我的思想填充'&'自動,因爲什麼OP張貼沒有意義:-DI不知道'Symbol#to_proc'使用'public_send',這是很好的知道(以及一個好的設計決策,我可能會添加) –