2011-12-31 9 views
0

このコードが正常に動作していない理由を私は理解していない:"呼び出し元"メソッドでテスト例外を捕捉できないのはなぜですか?

def test 
    raise Exception.new 'error' 
end 

def caller 
    begin 
    test 
    rescue =>e 
    puts e.message 
    end 
end 

caller 

を私はcaller方法でテストの例外をキャッチしたいが、caller方法は何かをキャッチされていないようです。

+0

FWIW、あなたは' begin'と 'end'をドロップすることができます。 'def caller; test;レスキュー例外=> e; puts e.message; end' – stephenmurdoch

+0

文章的なこととして、例外を発生させるときに' new'を使う必要はありません。 '例外を送出すると、 'error''で十分です。 –

答えて

0

試してみてください、しかし...

、あなたが救助したい例外の種類を指定する必要があります。すべての例外の基本クラスはExceptionなので、それをrescue Exception => eに変更すると動作します。また、何をしているから救出する方法の全体の体であるとき、あなたは明示的なBEGIN ... ENDをブロックする必要はありません...あなたのコードは動作しません

def test 
    raise Exception.new 'error' 
end 

def caller 
    test 
rescue Exception =>e 
    puts e.message 
end 

caller() 
+0

これもまた必ずしも真実ではありません。 **あなたがプログラムが扱うことができるよりも低いレベルの例外をキャッチしようとしているので、おそらく**は 'Exception => e 'を救済したくありません。 – coreyward

+0

言うまでもなく、「Exception」を救済することは、通常はうまく行かないことに言及すべきでした。しかし、このケースでは、「例外」が発生しているので、... –

2

rescueの例外の種類を指定する必要があります。あなたはexception=> var構文を使用すると月がそれに私を打つ

rescue Exception => e 
+0

これはうまくいきました。スローとraise文の違いを理解できません... –

+1

必ずしもそうではありません...私の答えを見てください。おそらく、あなたのアプリケーションが処理する準備ができているよりも低いレベルの例外をキャッチしているので、 'Exception => e'をレスキューするのは悪い考えです。 – coreyward

+0

@BenD、差をつけたり差し上げたり[この質問でカバーされていた](http://stackoverflow.com/questions/51021/what-is-the-difference-between-raising-exceptions-vs-throwing-exceptions-in-ルビー)。 – Jan

6

理由は、明示的に指定された例外タイプがないrescueは、のサブクラスであるStandardErrorをキャッチします。 がStandardErrorよりも高いため、rescueはそれを捕まえません。

一般に、より具体的な例外を使用したい場合は、ExceptionStandardError以上に使用する必要はほとんどありません。

これは、例えば、正常に動作します: `メソッド内で救助end`を開始し実行するときに

begin 
    raise StandardError.new 'Uh-oh!' 
rescue => e 
    p e.message 
end 

#=> Uh-oh! 
+0

「一般的に、より具体的な例外を使いたい」と同意した。追加された粒度は、 "戦闘条件"におけるフロー制御を扱う際に役立ちます。 –

関連する問題