将转换方法添加到Numeric会导致SystemStackError

时间:2012-03-08 21:58:14

标签: ruby

我正在尝试将转换方法添加到Numeric类,但是当我运行以下代码行时,我得到一个SystemStackError

puts 5.dollars.in(:euros)  # => 6.5
puts 1.dollar.in(:yen)

这是我的数字课程

class Numeric
  @@conversion_hash = {:dollar => {:yen => 0.013, :euros => 1.292, :rupees => 0.019}}

   def method_missing(method_id)
     name = method_id.to_s
     if name =~ /^dollar|yen|euros|rupee|$/
       self.send(name + 's')
     else
       super # pass the buck to superclass
     end
   end

   def dollars()
    puts "Called Dollars method"
    @current_currency = :dollar
    return self
   end

   def in(key)
     if @@conversion_hash.has_key?(@current_currency)
       puts "Current currency: #{@current_currency}"
       conversion_rate = @@conversion_hash[@current_currency]
       puts "Current conversion rate: #{conversion_rate}"
       if conversion_rate.has_key?(key)
         puts "we have that key"
         puts"What am I? #{self}"
         rate = conversion_rate[key]
         puts "Rate to multiply by #{rate}"
        return self.to_int * conversion_rate[key]
       end
     end
   end
 end

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

你的method_missing正在获得无限递归,因为你的正则表达式并不完全正确。尝试更改行:

if name =~ /^dollar|yen|euros|rupee|$/

为:

if name =~ /^dollar|yen|euros|rupee$/

额外的|导致任何东西与正则表达式匹配,因此任何其他方法都会以s的连续扩展后缀进行递归。

在这种情况下,当puts试图确定其参数的类型时,to_ary似乎试图调用respond_to?。我不确定为什么它不仅仅使用{{1}} - 它在C内部深处,所以我真的不知道发生了什么。

答案 1 :(得分:0)

您的解决方案过于复杂。 - 您不需要修改method_missing。 Armando版本工作正常。 - 你应该简单的美元定义哈希加 - 找到从方法中再次调用method_missing的方法(这是你的作业)。 工作解决方案只有1行代码+ 2行def surronding。