2

我正在做一个练习,我必须创建一个罗马到阿拉伯数字转换器。据我所知,下面的代码完全符合 kosher 标准,但是在运行测试时我不断收到错误消息。Ruby 认为第 37 行有一个未定义的方法或变量(在下面的注释中注明)。

我想知道我的 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 
4

2 回答 2

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并调用您需要的方法,而无需将其保存到变量中并占用内存。我还arabic_number从您的方法中删除了变量,因为您正在调用convert_and_add(roman_string),将其添加到变量中,然后返回变量。因为convert_and_add(roman_string)是该方法处理的最后一件事,所以无论如何它都会在没有变量的情况下返回它。

如果您从不打算在实例中使用这些方法,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
于 2012-04-25T20:33:10.517 回答
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

然后你需要创建一个实例并调用 convert 方法:

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')
于 2012-04-25T20:26:07.963 回答