動的例外マッチャーを使用したレベルアップ`rescue`
Rubyでrescue句を使用する場合、どの種類の例外をレスキューするかを指定できます。あなたがする必要があるのは、次のような例外クラスのリストを提供することだけです:
begin
raise RuntimeError
rescue RuntimeError, NoMethodError
puts "rescued!"
end
しかし、コードを記述したときに例外クラスがどうなるかわからない場合はどうでしょうか。最も明白な答えは、すべての例外をレスキューし、ある種のテストを実行してから、合格しなかった例外を再発生させることです。このようなもの:
begin
raise "FUBAR! The ship's going down!"
rescue => e
raise unless e.message =~ /^FUBAR/
... do something ...
end
しかし、それはとても退屈です!さらに、それはあまりドライなアプローチではありません。どういうわけか、条件に一致する例外のみをレスキューするようにレスキュー句に指示できれば、はるかに興味深いでしょう。そしてこれはRubyなので、私たちはそれを行うことができます!
レスキューブロック内で例外が発生すると、rubyインタープリターは、指定された例外クラスのリストに対して例外のクラスをチェックします。一致するものがある場合、例外は救出されます。
マッチングは次のようになります:
exception_classes_to_rescue.any? do |c|
c === raised_exception.class
end
Rubyの他のすべての演算子と同様に、===
単なる方法です。この場合、それはc
のメソッドです。 。では、独自の===
を定義したらどうなるでしょうか。 方法は?
以下の例では、Anything
という名前のクラスを作成しています。 ここで、Anything === x
xの任意の値に対してtrueを返します。このクラスをレスキューの引数として指定すると、すべての例外がレスキューされます。
class Anything
def self.===(exception)
true
end
end
begin
raise EOFError
rescue Anything
puts "It rescues ANYTHING!"
end
すべての例外を救済するためのはるかに優れた方法がありますが、このコードは2つのことを示しているので興味深いものです。
-
Exception
から継承しないレスキュー句クラスを指定できます 、===
を実装している限り -
===
を制御する場合 、どの例外をレスキューするかを制御できます。
私たちが今知っていることを知っているので、例外のメッセージがパターンに一致する場合にのみ例外を救済するコードを書くのは簡単です。
class AllFoobarErrors
def self.===(exception)
# rescue all exceptions with messages starting with FOOBAR
exception.message =~ /^FOOBAR/
end
end
begin
raise EOFError, "FOOBAR: there was an eof!"
rescue AllFoobarErrors
puts "rescued!"
end
例外オブジェクトにアクセスできるため、マッチャーはそのオブジェクト内に含まれるすべてのデータを使用できます。
「重大度」と呼ばれるカスタム属性を持つ例外があると少し想像してみてください。例外の「重大度の低い」発生をすべて飲み込みたいが、「重大度の高い」発生はすべて通過させます。あなたはそのようにそれを実装するかもしれません:
class Infraction < StandardError
attr_reader :severity
def initialize(severity)
@severity = severity
end
end
class LowSeverityInfractions
def self.===(exception)
exception.is_a?(Infraction) && exception.severity == :low
end
end
begin
raise Infraction.new(:low)
rescue LowSeverityInfractions
puts "rescued!"
end
これらはすべてかなりクールですが、多くの定型コードが含まれています。マッチャーごとに個別のクラスを手動で定義する必要があるのは過剰なようです。幸い、少しのメタプログラミングを使用することで、これをかなり乾かすことができます。
以下の例では、マッチャークラスを生成するメソッドを定義しています。ブロックを介してマッチングロジックを提供すると、マッチングジェネレーターが===
内のブロックを使用する新しいクラスを作成します。 メソッド。
def exceptions_matching(&block)
Class.new do
def self.===(other)
@block.call(other)
end
end.tap do |c|
c.instance_variable_set(:@block, block)
end
end
begin
raise "FOOBAR: We're all doomed!"
rescue exceptions_matching { |e| e.message =~ /^FOOBAR/ }
puts "rescued!"
end
Rubyの多くのクールなトリックのように、これがすべて狂気なのか素晴らしいアイデアなのかを完全に判断することはできません。多分それは両方の少しです。この手法を最初の選択肢として利用することは絶対にお勧めしませんが、上記のような重大度に基づいて例外を救済したい状況でどのように役立つかはわかります。いずれにせよ、それはあなたのツールベルトの別のツールです!
-
Pryでの例外の処理
あなたが私のようなら、あなたはRailsコンソールをよく使います。そして今では、PryがRailsコンソールに起こる最良のことであることに誰もが同意していると思います...まあ、これまで。 組み込みのこじ開けは、昔ながらのIRBに比べて、例外を除いて作業をはるかに簡単にするいくつかの非常に優れた機能です。 完全なバックトレースを表示 Pry(またはそのことについてはIRB)で例外が発生すると、バックトレースの短縮バージョンが表示されます。通常はこれで十分ですが、常にそうとは限りません。 pryでは、wtf -vコマンドを使用して、最新の例外の完全なバックトレースを確認できます。 -vフラ
-
ダイナミック ロック機能で Windows 10 を保護する方法
Windows 10 が追加した新機能の 1 つに、「動的ロック」があります。これは、Windows 10 で提供されるもう 1 つの非表示の機能であり、Creators の更新で開始されました。しかし、多くのユーザーはまだこの機能を認識していません. この記事では、動的ロックとは何か、またその使用方法について説明します。 Windows 10 の「ダイナミック ロック」とは? 動的ロックは、Microsoft によって追加された Windows 10 の機能です。この機能は、ユーザーが Bluetooth 経由でコンピュータまたはラップトップをロックするのに役立ちます。コンピューターをロ