用于在类中调用方法的Ruby语法

时间:2012-04-25 20:21:27

标签: ruby methods

我正在进行一项练习,我必须创建一个罗马到阿拉伯数字转换器。据我所知,下面的代码完全是犹太的,但是当我运行我的测试时,我一直收到错误。 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 

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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')