2016-06-21 32 views
0

我正在研究叫做機器人名稱的編碼挑戰。我也有測試。該計劃通過了所有的測試。代碼如下..爲什麼程序通過了所有的測試,如果我在方法中使用常規的if語句,但是在使用三元運算符時表示「堆棧層次太深」?

class Robot 
    attr_accessor :name 
    @@robots = [] 
    def initialize 
    @name = self.random_name 
    @@robots << self.name 
    end 

    def random_name 
    name = '' 
    2.times do 
     name << ('a'..'z').to_a.sample 
    end 
    3.times do 
     name << (1..9).to_a.sample.to_s 
    end 
    no_duplicate(name.upcase) 
    end 

    def reset 
    @name = self.random_name 
    end 

    def no_duplicate(name) 
    if @@robots.include? name 
     reset 
    else 
     name 
    end 
    end 
end 

如果你需要看測試文件,你可以看看它在這裏robot_name_tests

然後我開始重構,其中的第一件事是重構no_duplicate方法。因此,重構代碼看起來像這樣

class Robot 

    ... 
    # the rest of code stayed the same 

    def no_duplicate(name) 
    @@robots.include? name ? reset : name 
    end 
end 

使用此版本所有測試顯示SystemStackError: stack level too deep。爲什麼它考慮到提供的代碼在這兩種情況下都會出現這種錯誤以及幕後發生了什麼?謝謝!

回答

5

我喜歡你的詩歌模式代碼但它導致你在這裏陷入困境。

一種方法還挺保持在詩歌模式,但是解決您的運營商優先考慮的問題是要做到這一點:

def no_duplicate(name) 
    (@@robots.include? name) ? reset : name 
    end 

更新:如果你在大公司工作的編碼規範,你需要使它多一點無聊。我認爲這是顯而易見的,但畫廊正確地注意到通常的解決方案:

@@robots.include?(name) ? reset : name 
+0

這工作完美!謝謝!但爲什麼這個混淆的紅寶石呢?因爲「名字」?每次使用這種類型的語句時都不會感到困惑。爲什麼在這種情況下? –

+0

因爲? :運算符的綁定比函數參數更接近。也就是說,Ruby正在評估:'@@ robots.include?(name?reset:name)' – DigitalRoss

+0

明白了!謝謝你的解釋。 –

相關問題