2016-09-22 24 views
1

我想要一個包含滾動10個骰子(例如)的結果的向量。我可以這樣做:如何使用`:rand`作爲map/collect的一元方法?

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

但是,這給了我一個「錯誤的參數數目」錯誤:

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

有一個免費的點對點方式的rand的一個參數版本傳遞給map

回答

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不帶參數的行爲,這是該方法的Float 0和1之間

Method#to_proc傳遞所有參數(它畢竟已經有了它的接收器),所以在這種情況下,它將一次又一次地呼叫

self.rand(6) 

。當然可以工作,因爲selfObject,Object包括Kernel,而rand定義在Kernel中。原因很簡單,

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

map沒有任何參數,但你傳遞一個參數:

這不會正常工作。

+0

太好了,謝謝。我不應該在一個我沒有足夠信息的地方跳下一個結論,因爲我經常對其他人說:-把我說得對,對我來說似乎有點笨拙,但是每種語言都有自己的成語 – rici

+1

技術上在OP的情況下,它不會調用任何東西,因爲OP只是將一個符號傳遞給'map','map'不接受任何其他參數而不是一個塊,用符號處理'&:rand', 「私人方法'蘭特'6叫:Fixnum」 – engineersmnky

+1

@engineersmnky:啊,你是對的,我的思想填充'&'自動,因爲什麼OP張貼沒有意義:-DI不知道'Symbol#to_proc'使用'public_send',這是很好的知道(以及一個好的設計決策,我可能會添加) –

3

你可以寫:

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

這將是乾淨的方式來寫它:

10.times.map { rand(6) } 

寫作這種方式可以更容易地看到被傳遞到rand什麼說法。

+0

是的,謝謝,但我意識到這一點。在實際應用中,並不是所有的骰子都有相同數量的邊,所以我真的需要將'rand'映射到一個矢量上。不過,我不想在這個問題上討論這個問題。 – rici

相關問題