`method_missing': stack level too deep (SystemStackError)
1971 ワード
今日はmethodについて面白い話に出会った.missingのコード:
method_についてmissing、ancestors chainで変更方法が見つからない場合、rubyはmethod_を実行します.missingメソッド
このコードの意味はmethod_を書き換えることですmissingメソッドは、r.bobを実行するとbobメソッドが定義されていないためmethod_missing
メソッドでは、人名を大文字に変換し、3回ループしてランダム数を得ると、期待される結果は次のようになります.
4....
2....
7....
BOB got a 7
しかし実行結果はデッドサイクルであり、最後にプログラムは異常を投げ出す:`method_missing': stack level too deep (SystemStackError)
問題の原因はこの最後の文でnumber変数を得た:「#{person}got a#{number}」
ここでnumber変数はblokで定義されており、blokの外でnumberはすでに作用範囲を超えており、rubyは変数であることを知らず、カッコをつけない方法として呼び出され、method_が再呼び出されるmissingメソッド、このように繰り返して、死の循環になりました
だからblockの外でnumber=0を定義して、プログラムは正しく実行することができます
また、このようなトラブルを避けるために、ある方法を実行すると、どのように処理するか分からないので、Kernelのmethod_に戻ることを覚えておいてください.missingメソッド.
class Roulette
def method_missing(name, *args)
person = name.to_s.capitalize
3.times do
number = rand(10) + 1
puts "#{number}..."
end
"#{person} got a #{number}"
end
end
r = Roulette.new
puts r.bob
method_についてmissing、ancestors chainで変更方法が見つからない場合、rubyはmethod_を実行します.missingメソッド
このコードの意味はmethod_を書き換えることですmissingメソッドは、r.bobを実行するとbobメソッドが定義されていないためmethod_missing
メソッドでは、人名を大文字に変換し、3回ループしてランダム数を得ると、期待される結果は次のようになります.
4....
2....
7....
BOB got a 7
しかし実行結果はデッドサイクルであり、最後にプログラムは異常を投げ出す:`method_missing': stack level too deep (SystemStackError)
問題の原因はこの最後の文でnumber変数を得た:「#{person}got a#{number}」
ここでnumber変数はblokで定義されており、blokの外でnumberはすでに作用範囲を超えており、rubyは変数であることを知らず、カッコをつけない方法として呼び出され、method_が再呼び出されるmissingメソッド、このように繰り返して、死の循環になりました
だからblockの外でnumber=0を定義して、プログラムは正しく実行することができます
class Roulette
def method_missing(name, *args)
person = name.to_s.capitalize
number = 0
3.times do
number = rand(10) + 1
puts "#{number}..."
end
"#{person} got a #{number}"
end
end
r = Roulette.new
puts r.bob
また、このようなトラブルを避けるために、ある方法を実行すると、どのように処理するか分からないので、Kernelのmethod_に戻ることを覚えておいてください.missingメソッド.
class Roulette
def method_missing(name, *args)
person = name.to_s.capitalize
super unless %w[Bob Frank Bill].include?(person)
number = 0
3.times do
number = rand(10) + 1
puts "#{number}..."
end
"#{person} got a #{number}"
end
end
r = Roulette.new
puts r.bob