31

私のアプリケーション(Ruby 1.9.2)は、ネット接続の切断など、さまざまな例外を発生させる可能性があります。私rescue Exception => eは、それからcase/whenそれらを異なる方法で処理するために行いますが、いくつかのエラーが私のケースを直接通過しelseます。

rescue Exception => e
    p e.class
    case e.class
        when Errno::ECONNRESET
            p 1
        when Errno::ECONNRESET,Errno::ECONNABORTED,Errno::ETIMEDOUT
            p 2
        else
            p 3
    end
end

プリント:

Errno::ECONNRESET
3
4

2 に答える 2

57

これは、===演算子がクラスでどのように機能するかによるものですClass

caseステートメントは、評価対象のオブジェクトのメソッドを内部的に呼び出します。クラス===をテストする場合は、に対してテストするだけで、に対してテストするだけです。それは、e.classがクラスであるため、ケースに該当するためです。eee.classe.classwhen Class

rescue Exception => e
    case e
        when Errno::ECONNRESET
            p 1
        when Errno::ECONNRESET,Errno::ECONNABORTED,Errno::ETIMEDOUT
            p 2
        else
            p 3
    end
end

ええ、Rubyは時々奇妙なセマンティクスを持つことができます

于 2010-09-27T06:41:37.753 に答える
1

それは、クラスを参照するか定数を参照するかによって異なります。たとえば、特定のタイプの検出を機能させるには、次のcaseステートメントを使用する必要がありました。

def fail(exception_error)
exception = exception_error
case exception.class
  when /HTTPClient::ConnectTimeoutError.new/
    status = 'CONNECTION TIMEOUT'
    connection_status = 'DOWN'
  else
    status = 'UNKNOWN FAILURE'
    connection_status = 'DOWN'
end

しかし、それは私が定数ではなく実際の例外クラスで作業しているためです。HTTPCLientは、実際のクラスオブジェクトを生成しています。

class TimeoutError < RuntimeError
end  
class ConnectTimeoutError < TimeoutError
end

ここに不可解な事実があります:

error = HTTPClient::ConnectTimeoutError.new
HTTPClient::ConnectTimeoutError === error
#=> true
error === HTTPClient::ConnectTimeoutError
#=> false

それをどうすればいいのかわからない。

于 2014-10-25T18:25:53.120 に答える