2012-04-25 63 views
2

我正在進行練習,我必須創建一個羅馬到阿拉伯數字轉換器。據我所知,下面的代碼完全是猶太教,但是當我運行我的測試時,我總是收到一個錯誤。 Ruby認爲第37行有一個未定義的方法或變量(注意下面的註釋)。用於調用類中方法的Ruby語法

我想知道我的snytax是否關閉或者是否是其他東西。建議?

class ArabicNumeral 

    def replace_troublesome_roman_numerals(letters) 
    tough_mappings = {"CM" => "DCCCC", "CD" => "CCCC", "XC" => "LXXXX", "XL" => "XXXX", "IX"=> "VIIII", "IV" => "IIII"} 
    tough_mappings.each { |roman, arabic| letters = letters.gsub(roman, arabic) } 
    letters 
    end 

    def convert_and_add(letters) 
    digits = { "M" => 1000, "CM" => 900, "D" => 500, "C" => 100, "XC" => 90, "L" => 50, "XL" => 40, "X" => 10, "IX" => 9, "V" => 5, "IV" => 4, "I" => 1} 
    letters = letters.split("") 
    letters.inject(0) do |sum, letter| 
     arabic = digits[letter] 
     sum += arabic 
    end 
    end 

    def self.convert(letters) 
    roman_string = replace_troublesome_roman_numerals(letters) ###LINE 37! 
    arabic_number = convert_and_add(roman_string) 
    arabic_number 
    end 
end 

回答

3

這裏的問題是,你正在呼籲行37 replace_troublesome_roman_numerals(letters)的方法。問題是方法self.convert(letters)是一個類方法。你可以這樣調用:

ArabicNumeral.convert(letters) 

但是,它包含一個呼叫實例變量(即該replace_troublesome_roman_numerals(letters)我前面提到的

def self.convert(letters) 
    roman_string = ArabicNumeral.new.replace_troublesome_roman_numerals(letters) 
    ArabicNumeral.new.convert_and_add(roman_string) 

end 

這將創建的ArabicNumeral實例,並調用你的方法。因爲你調用了convert_and_add(roman_string),把它加到變量中,然後返回變量,因爲convert_and_add(roman_string)是該方法處理的最後一件事情,所以我們需要將變量arabic_number刪除,它會返回任何沒有變量的方式。

如果你從來沒有計劃在ArabicNumeral的實例中使用這些方法,那麼我會建議使所有的方法級別級別或包裝在Module,你會包括在你的項目。如果您不打算在ArabicNumeral課程之外使用它們,請考慮將它們放在protectedprivate之後,同時保留convert(letters)可用。

class ArabicNumberal 

def self.convert(letters) 
    # Code... 
end 

private 

def self.replace_troublesome_roman_numerals(letters) 
    # Code... 
end 

def self.convert_and_add(roman_string) 
    # Code... 
end 

end 
+1

謝謝!我最終將所有方法都提升到了「課堂級別」。我彈出「自我」。在每個方法名稱前,現在我所有的測試都通過了。 – 2012-04-25 20:42:48

2

好的...首先,你正在嘗試使用一個類的實例方法。

這一問題可以通過改變方法來解決從轉換:

def self.convert(letters) 
    roman_string = replace_troublesome_roman_numerals(letters) ###LINE 37! 
    arabic_number = convert_and_add(roman_string) 
    arabic_number 
end 

要:

def convert(letters) 
    roman_string = replace_troublesome_roman_numerals(letters) ###LINE 37! 
    arabic_number = convert_and_add(roman_string) 
    arabic_number 
end 

然後,你需要創建一個實例,並調用轉換方法:

x = ArabicalNumeral.new() 
x.convert('param') 

就是這樣。順便說一下,我建議你添加一個構造方法(在Ruby中被命名爲initialize)。

完整的腳本如下:

class ArabicNumeral 

    def replace_troublesome_roman_numerals(letters) 
    tough_mappings = {"CM" => "DCCCC", "CD" => "CCCC", "XC" => "LXXXX", "XL" => "XXXX", "IX"=> "VIIII", "IV" => "IIII"} 
    tough_mappings.each { |roman, arabic| letters = letters.gsub(roman, arabic) } 
    letters 
    end 

    def convert_and_add(letters) 
    digits = { "M" => 1000, "CM" => 900, "D" => 500, "C" => 100, "XC" => 90, "L" => 50, "XL" => 40, "X" => 10, "IX" => 9, "V" => 5, "IV" => 4, "I" => 1} 
    letters = letters.split("") 
    letters.inject(0) do |sum, letter| 
     arabic = digits[letter] 
     sum += arabic 
    end 
    end 

    def convert(letters) 
    roman_string = replace_troublesome_roman_numerals(letters) ###LINE 37! 
    arabic_number = convert_and_add(roman_string) 
    arabic_number 
    end 
end 

x = ArabicNumeral.new() 
puts x.convert('MDC')