Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

どの例外をキャッチするかを知るためのエレガントなトリックを救出します

以前にRubyの例外を処理したことがある場合は、どの例外をレスキューし、どの例外をレスキューしないかを指定できることをご存知でしょう。

begin
  raise ArgumentError
rescue ArgumentError
  # Rescues the `ArgumentError`
end

...そしてあなたはおそらくあなたが「親」を救うときあなたはその「子供」のすべても救うことを知っているでしょう。

begin 
  raise ArgumentError
rescue StandardError
  # Rescues `ArgumentError`, because it inherits from 
  # `StandardError`
end

私が「親」と「子」と言うとき、私は単にクラスの継承を指します。 Rubyソースコードのどこかにこれに相当するものがあります:

class ArgumentError < StandardError
   ...
end
興味深いトリック

これが私の質問です:Rubyは、指定されたクラスから特定の例外が継承されているかどうかをどのように知るのですか?

最も明白なアプローチは、is_a?を使用することです。 またはkind_of? 方法。次のように想像できます:

if the_exception.is_a?(StandardError)
   # do the rescue
end

しかし、それは起こりません。代わりに、Rubyはより興味深い===を使用します オペレーター。

if StandardError === the_exception
   # do the rescue
end

a === bを使用したことがない場合 、それは通常、「本質的にbによって定義されたグループに属しているか」という質問に答えますか?次にいくつかの例を示します。

(1..10) === 5             # true
('a'..'f') === "z"        # false

String === "hello"        # true
String === 1              # false

/[0-9]{3}/ === "hello123" # true
/[0-9]{3}/ === "hello"    # false

=== ==のような通常のルビーメソッドです 、自分で定義できます:

class RedThings
   def self.===(thing)
     thing.color == :red
   end
end

それで、私たちは何を知っていますか? rescue ===を使用します どの例外がレスキューされるかを決定します。そして、独自の===を定義できることを知っています。 方法。つまり、どの例外を救済するかをオンザフライで決定するクラスを作成できます。

class SevereMatcher
  def self.===(exception)
    exception.message =~ /severe/    
  end
end

begin
  raise RuntimeError, "Something severe happened"
rescue SevereMatcher
  # rescues all exceptions with the word "severe" in
  # the message, regardless of class.
end

このトリックを知ったら、唯一の制限はあなたの想像力です。

結論

認めます。動的例外マッチャーを作成する必要はないかもしれません。しかし、これは、===を使用するような一見些細な実装の詳細の非常に興味深い例です。 kind_of?の代わりに Rubyをはるかに柔軟で興味深いものにします。


  1. FedoraとUbuntu:どちらがあなたに適していますか?

    ああ、昔からの質問:どのディストリビューションを使うべきですか?さまざまなディストリビューションの多くのユーザーがあなたに自分のチームを選択してほしいと望んでいるため、それはしばしば論争を巻き起こします。ただし、2つのディストリビューションのうちの1つを提案するユーザーの圧倒的多数がしばしばいます。この記事では、FedoraとUbuntuを比較して、どちらが適しているかを調べます。 FedoraとUbuntuの基本 基本から始めましょう。この記事では、Fedora32WorkstationおよびUbuntu20.04LTSなどの各ディストリビューションの最新リリースについて説明します。 Fe

  2. Allo vs. WhatsApp:どちらがあなたに適していますか?

    AlloはWhatsAppから王冠を奪うことができますか?新しいメッセージングアプリは、すべての間違った理由でニュースを発信していますが、市場で最も人気のあるアプリに挑戦する価値はありますか?世界中で話題となったプライバシーの問題を除けば、全体的なユーザーエクスペリエンスの点で実際に優れているアプリはどれですか? どちらを使用すればよいかわからない場合は、こちらのガイドをご覧ください。それぞれの良い点を紹介し、自分で決めることができます。 WhatsAppを使用する理由 WhatsAppは私たちの多くにとってなじみのある友人であり、実際には予想よりも古いものです。もともとは2010年