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')