はじめに
if文を使う時に、この条件ならempty?かblank?はどっちを使う方が正しいだろう・・・、と迷ったことはありませんか?
rubyやrailsは多くの真偽判定メソッドを提供しています。
けれど、逆に多すぎることで混乱して、こんな時はどうなんだっけ?ということがたまに起きてしまいます。
なので、主要な真偽判定メソッド(nil?/empty?/blank?/present?)の挙動について色々と検証していきたいと思います。
環境
検証は下記バージョンで行いました。
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]
$ rails -v
Rails 5.1.6
rubyの真偽判定メソッド
下記サイトを参考に、それぞれのメソッドの説明を記載しました。
nil?
Rubyの標準メソッドです。
nilの場合のみtrueを返し、それ以外はfalseを返します。
empty?
Rubyの標準メソッドです。
空の文字列や空の配列の場合にtrueを返します。
nilやbooleanやintegerに対して呼び出すとNoMethodErrorが発生します。
blank?
railsで拡張された真偽判定メソッドです。
なので、railsが入っていないと使用できないので、注意が必要です。
nilまたは空のオブジェクトをチェックできます。
nil, false, "", " "(半角スペースのみ), [](空の配列), {}(空のハッシュ) のときにtrueを返します。
present?
blank?と同様、railsで拡張された真偽判定メソッドです。
なので、railsが入っていないと使用できないので、注意が必要です。
判定条件は、blank?の逆です。つまり。!blank?と同じ挙動を示します。
nil, false, "", " "(半角スペースのみ), [](空の配列), {}(空のハッシュ) 以外のときにtrueを返します。
参考サイト:Railsドキュメント
検証方法
rails consoleにて
test = ○ ←ここに色々な値を入れて検証
test.nil?
test.empty?
test.blank?
test.present?
検証結果
| nil? | empty? | blank? | present? | |
|---|---|---|---|---|
| nil | true | NoMethodError | true | false |
| true | false | NoMethodError | false | true |
| false | false | NoMethodError | true | false |
| 0 | false | NoMethodError | false | true |
| 123 数字 |
false | NoMethodError | false | true |
| "" 空 |
false | true | true | false |
| " " 半角スペース |
false | false | true | false |
| "hoge" 文字列 |
false | false | false | true |
| [] 空配列 |
false | true | true | false |
| ["fuga", "piyo"] 配列(値あり) |
false | false | false | true |
| {} ハッシュ(空) |
false | true | true | false |
| {:key => value} ハッシュ(値あり) |
false | false | false | true |
気になった点・興味深い点
-
empty?はnil/boolean/integerの時にNoMethodErrorを返す
→nil/boolean/integerが弾かれてしまうということは、判定できるのは"文字列"か"配列"に限定されてしまうっぽいですね。 -
falseの時に、blank?はtrueを返す
→blank?をnil?とempty?の合わせ技だと思って使っていると、ここの挙動の差に痛い目にあうかもですね。要注意です! -
" "(半角スペース)の時は、blank?はtrueを返す
→" "(半角スペース)はblank(=からっぽ)という基準に合致するようですね。
結論
検証結果を見てわかる通り、非常にややこしい結果になりました。
if文などを書く時に、なんとなくで真偽判定メソッドを使っていると思わぬ値で予想に反する挙動を示して、バグを生んでしまう可能性があるので、十分に気をつける必要があります。0や""(空)や" "(半角スペース)などは特に注意する必要がありそうですね。
さいごに
今回作った表は、忘れてしまった時に振り返り用として今後よく使うかもと思ったので、自分が見やすいように作りました。
ふとした時に参考になればいいなぁと思っています。