普段仕事で使っているRuby on Railsですが、ソースコードを読む機会もなかなかないので、試しにやってみることにしました
読めるようにするまで
以前書いた記事で読めるようにするまでの設定を画像キャプチャ付きで解説しましたので、よろしければこちらをご参照下さい
shitake4.hatenablog.com
読んだ箇所
silence_warnings
を今日は読んでみようと思います
どんな使い方だっけ?
読んでみる前にまずは使い方を調べてみます
Railsの日本語ドキュメントを見てみると
ブロックが継続する間$VERBOSEの値を変更し、その後リセットします。
silence_warnings { Object.const_set "RAILS_DEFAULT_LOGGER", logger }suppressメソッドを使用すると例外の発生を止めることもできます。このメソッドは、例外クラスを表す任意の数値を受け取ります。suppressは、あるブロックの実行時に例外が発生し、その例外が(kind_of?による判定で)いずれかの引数に一致する場合、それをキャプチャして例外を発生せずに戻ります。一致しない場合、例外はキャプチャされません。
# ユーザーがロックされていればインクリメントは失われるが、重要ではない suppress(ActiveRecord::StaleObjectError) do current_user.increment! :visits end
ソースコードを読んでみる
1. railsプロジェクトのactivesupportにある機能ですので、activesupportディレクトリのlib配下で def silence_warnings
を探してみます
2. 該当箇所が1箇所あったので、みてみます
1. activesupport > lib > active_support > core_ext > kernel > reporting.rb
# frozen_string_literal: true module Kernel module_function # Sets $VERBOSE to +nil+ for the duration of the block and back to its original # value afterwards. # # silence_warnings do # value = noisy_call # no warning voiced # end # # noisy_call # warning voiced def silence_warnings with_warnings(nil) { yield } end 省略 end
with_warnings
メソッドにブロックを渡してます。 そのブロック内で yield
しているので、元は silence_warnings
に渡したブロックです
たとえば、
silence_warnings { puts 'ブロック実行' }
このように書いた場合は、 {}の内容がwith_warnings
へそのままブロックとして渡すという感じになります
※ ブロックの詳しい説明は@kidach1氏のこちらの記事を参考にしてください qiita.com
silence_warnings
の処理を見てみます
省略 # Sets $VERBOSE for the duration of the block and back to its original # value afterwards. def with_warnings(flag) old_verbose, $VERBOSE = $VERBOSE, flag yield ensure $VERBOSE = old_verbose end 省略
仮引数flag
には nil
が入ります
次に変数の初期化処理 old_verbose, $VERBOSE = $VERBOSE, flag
で、$VERBOSE
がどんなものなのかわからなかったので、調べてみます
冗長メッセージフラグです。Rubyインタプリタへの コマンドラインオプション -v でセットされます。
警告レベルは三段階あり、それぞれ以下の通りです。
- nil
- 警告を出力しない
- false
- 重要な警告のみ出力 (デフォルト)
- true
- すべての警告を出力する
$VERBOSE に nil, false 以外を代入すると値は true になります。
$VERBOSE の値はコマンドラインオプション -W でも設定できます。 -W0 オプションで nil、 -W1 オプションで false、 -W2, -W オプションで true が設定されます。 -v オプションや -w オプションを指定した場合は true が設定されます。
$VERBOSE はグローバルスコープです。
引用:Ruby2.5.0リファレンスマニュアル#variable $-v
with_warningsメソッド内では
- ブロック実行前に
$VERBOSE
へ nilを入れることで警告を出力しないモードへと変更 yield
でブロックを実行- ブロック実行後、もともと設定されていた
$VERBOSE
へ設定し直すという処理になります
読んでみて
普段は使っていない機能だったので、どんな挙動するのか手探りで読んでました。使い所がまだ理解できていないので、このような機能があることを覚えておき、使えるようにしておくのが、良さそうだと思いました