🦁

<< と || の演算子の優先順序

2023/02/15に公開

tl;dr

  • <<|| より優先されるので () で括ろう

起きたこと

string_array = []
string_array << object&.property.presence || ''

ってやるとき property が nil だとしても、配列には nil が入る('' に補正されない)。

&. とか .presence で安全に nil にして || '' として空文字にする、みたいなイディオマティックなコードを書いてると起こりがちかも。

加えて、代入(=)の優先度は || より低いので、同じ右辺でも = だと StringClass << だと NilClass という動作になることにも注意したい。

上記のように文字列を期待しているとき nil.to_s は空文字('')となり特にエラーを起こさないため、問題に気付きにくい。

とりわけ "force_quote" をデフォルト(false)で作成した CSV の行データ配列でやっていると nil はクォートなし、'' はクォートありで出力されるという差としてのみ表れる。

  • コード
require "csv"
data = CSV.generate("", force_quotes: false) do |csv|
    row = []
    row << nil
    row << nil || ''
    row << (nil || '')
    row << ''
    csv << row
end
print(data)
  • 出力例
,,"",""

CSV を Excel などビジュアルエディタで編集すると問題に気付けない。

GitHubで編集を提案

Discussion