2015-07-06 28 views
2

我正在爲exerciseism.io進行練習 - 說明很長且與此問題無關,但您可以找到我的完整解決方案here將定製方法從自定義類傳遞到.map

基本上我有一個Robot,3類私有方法:

def rand_letters 
    ('A'..'Z').to_a[rand(26)] 
    end 

    def rand_numbers 
    (0..9).to_a[rand(10)] 
    end 

我試圖做的是這些傳遞給其他私有方法,像這樣:

def set_name 
    @name = ((1..2).map(&:rand_letters) + (3..5).map(&:rand_numbers)).join 
    end 

當我這樣做我收到錯誤:undefined method 'rand_letters' for 1:Fixnum。看過this question後,我認爲可能問題是我的班級沒有to_proc方法。不幸的是我不知道如何解決這個問題。我試圖讓我的課程從Proc繼承,但我堅持如何覆蓋to_proc。任何幫助指引我在正確的方向將不勝感激。

+0

兩問題:是否需要使用短語法('.map(&:method)'),如果是,是否允許猴子修補「Fixnum」和「String」cl驢? – ndn

+0

你還期望什麼結果 - 你想要一個隨機的字母/數字映射到範圍內的每個元素? – ndn

+0

不,它不是要求的一部分,只是有人在評論中提到了它(你可以在鏈接到完整的解決方案中看到它們),並且他們提出了map(&:method) – SoSimple

回答

2

第一:你可以使用array.sample而不是array[rand(x)]從數組中獲得一個隨機元素。

此外,還可以通過更換n.times.map(1..n).map

(2.times.map { rand_letters } + 3.times.map { rand_numbers }).join 

但使用map感覺直覺上我。如果我們可以簡單地抓取3個隨機字母,這會不會容易得多?

這可以通過返回Enumerator而不是單個值來實現。複數命名已經表明rand_方法應該返回多個值:

def rand_letters 
    return enum_for(__method__) unless block_given? 
    loop { yield ('A'..'Z').to_a.sample } 
end 

def rand_numbers 
    return enum_for(__method__) unless block_given? 
    loop { yield (0..9).to_a.sample } 
end 

這讓我們打電話Enumerable#take

(rand_letters.take(2) + rand_numbers.take(3)).join 
#=> "ZJ010" 

或者使用[...]文字:

[rand_letters.take(2), rand_numbers.take(3)].join 
+0

我實際上最終使用'Array#sample',所以非常感謝您提及它。並感謝這個奇妙的詳細解釋。這真的讓我覺得! – SoSimple

+1

@SoSimple注意'sample(n)'返回'n' * unique *元素,即你在[當前代碼]中排除了重複元素(http://exercism.io/submissions/85c7697232034453baeb130b8982eea3)。 – Stefan

0

這裏是解決方案:當您使用map(&:rand_letters)語法您發送郵件到集合中的每個元素

def rand_letters 
    ('A'..'Z').to_a[rand(26)] 
end 

def rand_numbers 
    (0..9).to_a[rand(10)] 
end 

p ((1..2).map { rand_letters } + (1..3).map { rand_numbers }).join 

。在我們的例子Fixnum對象收到消息(:rand_letters),因爲它不是在類Fixnum

在我的例子消息:rand_letters:rand_numbers不會傳遞到Fixnum實例定義不能respont該消息,但self,在哪裏定義Thery。

在這裏,你怎麼能一個類中使用它:

所有的
class A 
    def rand_letters 
    ('A'..'Z').to_a[rand(26)] 
    end 

    def rand_numbers 
    (0..9).to_a[rand(10)] 
    end 

    def name  
    (1..2).map { rand_letters } + (1..3).map { rand_numbers }.join 
    end 
end 

A.new.name 
相關問題