为什么我得到SystemStackError?

问题描述:

module CallableDict 
    def method_missing method 
    puts x["#{method}"] 
    end 
end 

上面的代码是我的模块,它使得哈希键可调用。当我虽然运行...为什么我得到SystemStackError?

require 'callabledict' 
x = {"foo" => "ruby"} 
x.extend CallableDict 
x.foo 

我得到以下...

SystemStackError: stack level too deep 
    from /Users/Solomon/.rvm/rubies/ruby-1.9.3-p125/lib/ruby/1.9.1/irb/workspace.rb:80 
Maybe IRB bug! 

为什么?我可以解决这个问题吗?

+1

我猜你叫''中method_missing' x'这是一个递归调用,因为这也是一次又一次地呼吁X。 – Peterdk 2012-04-28 12:10:51

实际上xself这样你就可以把它改写这样的:

module CallableDict 
    def method_missing method 
    puts self["#{method}"] 
    end 
end 
+0

+1,这是缺少的'x',而不是'方法'。 – 2012-04-28 12:09:40

method_missing实施,x被视为方法的名字,如红宝石还没有看到x在右侧的变量范围。当解释器看到x["#{method}"]时,它认为您正在索引到从名为x的方法返回的哈希或其他对象。因为没有叫做x的方法,所以Ruby会调用你的method_missing,它会再次调用它自己,重复这个过程直到Ruby进入堆栈溢出。

修复很简单。作为@nash如上所述,你必须用self取代x,因为在method_missingx没有任何意义,但self是相同的(在C而言,它们是同一个指针)。此外,您还可以使通过在method_missing实施这样的代码更易读:

puts self[method.to_s]