レスキューブロック外でのRuby例外の処理
コードがその例外のライフサイクルを制御していない場合でも、最新の例外を取得できると便利なことがよくあります。アプリケーションに基本的なクラッシュ検出を追加したいとします。キャッチされなかった例外の結果として発生したクラッシュに関する追加情報をログに記録したい。
最初のステップは、アプリケーションが終了するたびに実行されるハンドラーを追加することです。 Rubyカーネルのat_exitメソッドを使用してこれを行うのは非常に簡単です。
at_exit
puts "the app exited"
end
しかし、例外の結果として終了コールバックが呼び出されたかどうかをどのように知ることができますか?さて、Rubyは不可解な名前の$!
を提供します グローバル変数。これには、現在のコールスタックのどこかで発生した最近発生した例外が含まれています。
$!
を使用するのは簡単です 例外が原因でプログラムが終了しているかどうかを検出します。次のようになります:
at_exit do
save_error_to_log($!) if $!
end
$!
の制限
残念ながら、$!
メソッドは、現在の呼び出しスタックのどこかで例外が発生した場合にのみ機能します。例外を救済する場合は、$!
にアクセスしてみてください レスキュー条項の外では、nilになります。
begin
raise "x"
rescue
puts $! # => RuntimeError
end
puts $! # => nil
これは、$!
を意味します IRBのようなシェルの内部ではかなり役に立たない。多くの場合、IRBでは、メソッドを実行して例外を取得します。その例外オブジェクトを入手したい場合があります。しかし、$!
これでは機能しません。
irb(main):001:0> 1/0
ZeroDivisionError: divided by 0
from (irb):1:in `/'
irb(main):002:0> $!
=> nil
$を回避する! PRY付き
PRYは$!
の制限を回避します 独自のローカル変数_ex_
を追加する 。この変数には、キャッチされていない最新の例外が含まれています。
[1] pry(main)> raise "hi"
RuntimeError: hi
from (pry):1:in `__pry__'
[2] pry(main)> _ex_
=> #<RuntimeError: hi>
PRYがこれを実行できる理由は、PRYまたはIRB内にキャッチされない例外が実際にはないためです。シェル自体が例外をキャッチし、適切にフォーマットされたエラーメッセージとして表示します。
以下のPRYソースの関連ビットをコピーしました。コマンドを評価するコードがbegin/rescue/endブロック内にラップされていることがわかります。レスキュー可能な例外が発生すると、PRYは例外をself.last_exceptionに保存し、後で_ex_
に割り当てられます。 。
# Excerpted from the PRY source at https://github.com/pry/pry/blob/623306966bfa86890ac182bc8375ec9699abe90d/lib/pry/pry_instance.rb#L273
begin
if !process_command_safely(line)
@eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty?
end
rescue RescuableException => e
self.last_exception = e
result = e
Pry.critical_section do
show_result(result)
end
return
end
おそらく、$!
のような変数名を見つけるでしょう。 目に少し難しい?幸い、Rubyには「English」と呼ばれるモジュールが含まれています。このモジュールは、他の方法ではロボットのcusswordsのように見える多くのグローバル変数の英語バージョンを提供します。
$!
の同義語 $ERROR_INFO
です 。通常$!
を使用する場所ならどこでも使用できます 。
require "English"
begin
raise "x"
rescue
puts $ERROR_INFO # => RuntimeError
end
そして、他の英語の同等物のほとんどは、このブログ投稿のトピックとは何の関係もありませんが、私はそれらをキックに含めています。英語の変数は左側にあります。オリジナルは右側にあります。
$ ERROR_INFO | $! |
$ ERROR_POSITION | $ @ |
$ FS | $; |
$ FIELD_SEPARATOR | $; |
$ OFS | $、 |
$ OUTPUT_FIELD_SEPARATOR | $、 |
$ RS | $ / |
$ INPUT_RECORD_SEPARATOR | $ / |
$ ORS | $ \ |
$ OUTPUT_RECORD_SEPARATOR | $ \ |
$ INPUT_LINE_NUMBER | $。 |
$ NR | $。 |
$ LAST_READ_LINE | $ _ |
$ DEFAULT_OUTPUT | $> |
$ DEFAULT_INPUT | $ < |
$ PID | $$ |
$ PROCESS_ID | $$ |
$ CHILD_STATUS | $? |
$ LAST_MATCH_INFO | $〜 |
$ IGNORECASE | $ = |
$ ARGV | $ * |
$ MATCH | $& |
$ PREMATCH | $ ` |
$ POSTMATCH | $‘ |
$ LAST_PAREN_MATCH | $ + |
-
Ruby Mapメソッドの使用方法(例付き)
Mapは、配列、ハッシュ、範囲で使用できるRubyメソッドです。 マップの主な用途は、データを変換することです。 例 : 文字列の配列が与えられた場合、すべての文字列に目を通し、すべての文字を大文字にすることができます。 または、Userのリストがある場合 オブジェクト… 変換できます 対応するメールアドレス、電話番号、またはその他の属性のリストにそれらを追加します Userで定義 クラス。 これを行う方法を正確に見てみましょう! ルビーマップ構文 マップの構文は次のようになります: array = [a, b, c] array.map { |string| string.
-
RubyでN-Queensの問題を解決する
N-Queensは、 N*NボードにN個のクイーンを配置する必要がある興味深いコーディングチャレンジです。 。 次のようになります: 女王はすべての方向に移動できます: 垂直 水平 対角線 解決策(多くの場合があります)は、すべてのクイーンをボードに配置する必要があります。 &すべての女王は他のすべての女王の手の届かないところにいる必要があります。 この記事では、私がどのようにして解決策を思いついたのかを学びます。 計画 この種の課題を解決するときは、まず、計画を平易な英語で書き留めることから始めるのがよいでしょう。 これは、問題が何であるか、およびそれを解決するための手