Hash#fetchでブロックを記述した場合の挙動 | rails commit log流し読みを読んでみた

f:id:sktktk1230:20180726121250p:plain

1. 概要

@y_yagiさんのrails commit log流し読みを読んでいての学びを書いてみます

2. 読んだエントリ

y-yagi.hatenablog.com

3. わからなかったこと

  1. PRの中の処理に書かれていたHash#fetchにブロックを渡すとどうなるか
def log_to_stdout?
  options.fetch(:log_to_stdout) do
    options[:daemon].blank? && environment == "development"
  end
end

4. PRを読んでみる

対象のPR

github.com

1. どんな修正内容?

railties/lib/rails/commands/server/server_command.rbの修正です。
rails serverでlogをstdoutに出力するかどうかをrails serverコマンドの引数で指定出来るようにしています。
rails serverコマンドに--no-log-to-stdoutを引数に指定した場合、developmentでもlogがstdoutに出力されないようになっています。
引用:rails commit log流し読み(2018/07/09)

5. PR読んでてわからない部分調べてみた

1. Hash#fetch にブロックを渡すとどんな挙動になる?

fetch(key, default = nil) {|key| ... } -> object[permalink][rdoc]
key に関連づけられた値を返します。該当するキーが登録されてい ない時には、引数 default が与えられていればその値を、ブロッ クが与えられていればそのブロックを評価した値を返します。
fetchはハッシュ自身にデフォルト値が設定されていても単に無視します(挙動に変化がありません)。
引用:Ruby 2.5.0 リファレンスマニュアル Hash#fetch

ハッシュにkeyが存在しない場合は、ブロックの評価値が戻り値となるようです

実際の挙動を確認してみました

f:id:sktktk1230:20180710113633p:plain

ブロックの評価値trueが戻り値となりました

ここまでを踏まえ、さきほどのPRの内容を見てみると、

def log_to_stdout?
  options.fetch(:log_to_stdout) do
    options[:daemon].blank? && environment == "development"
  end
end

optionsに log_to_stdout が設定されていない場合、options[:daemon]がblankかつ環境がdevelopmentだとログ出力をするという処理になります