🦁
<< と || の演算子の優先順序
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 などビジュアルエディタで編集すると問題に気付けない。
Discussion