2012-03-17 5 views
6
class MyClass 
    def method_missing(name, *args) 
    name = name.to_s 
    10.times do 
     number = rand(100) 
    end 
    puts "#{number} and #{name}" 
    end 
end 

こんにちは、私はこのルーシーを行使していますが、この非再帰関数ではこのコードを使用するとスタックレベルが深すぎます。スタックレベルがRubyで深すぎます

x = MyClass.New 
x.try 

答えて

11

あなたのコードの問題はmethod_missing()範囲から外れるtimes()内で定義されたnumber変数です。したがって、その行が実行されると、Rubyはそれをselfのメソッド呼び出しとして解釈します。

通常の場合、NoMethodError例外が発生しているはずです。ただし、MyClassのメソッドmethod_missing()をオーバーライドしているため、この例外は発生しません。代わりに、スタックオーバーフローメソッドnumber()が呼び出されます。

このような問題を回避するには、許可されているメソッド名を指定してください。たとえば、try, test, and my_methodメソッドがMyClassで呼び出されるだけで、そのような問題を回避するには、method_missing()にこれらのメソッド名を指定する必要があるとします。一例として、

class MyClass 
    def method_missing(name, *args) 
    name = name.to_s 
    super unless ['try', 'test', 'my_method'].include? name 
    number = 0 
    10.times do 
     number = rand(100) 
    end 
    puts "#{number} and #{name}" 
    end 
end 

あなたが本当にそれを使用しないよう、method_missing()を必要としない場合。いくつかの良い選択肢がありますhere

+1

あなたは私より31秒早いです。しかし、私は '#{number}と#{name}"が '10.x'の中にあると考えられていたが、そうではないと思うだろう。 –

+1

あなたは私よりも速かった! :)と私はスーパー(ビッグ+1)についてのビットを追加するとは思っていませんでしたが、数字に関して、私は彼らが本当にこのような何かを意味すると思う 'number = Array.new(10){rand(100)} .reduce(:+) ' – iain

+0

はい、あなたは正しいです。 putsはブロック内にないので、現在はtimes()を持つのは意味がありません:) –

関連する問題