rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった

## はじめに
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ドキュメント](http://railsdoc.com/active_support#%E7%9C%9F%E5%81%BD%E5%88%A4%E5%AE%9A)

## 検証方法

rails consoleにて

```
test = ○ ←ここに色々な値を入れて検証
test.nil?
test.empty?
test.blank?
test.present?
```
## 検証結果

|       |nil?|empty?|blank?|present?|
|:-----:|:--:|:----:|:----:|:------:|
|nil|<font color="Blue">true</font>|NoMethodError|<font color="Blue">true</font>|<font color="Red">false</font>|
|true|<font color="Red">false</font>|NoMethodError|<font color="Red">false</font>|<font color="Blue">true</font>|
|false|<font color="Red">false</font>|NoMethodError|<font color="Blue">true</font>|<font color="Red">false</font>|
|0|<font color="Red">false</font>|NoMethodError|<font color="Red">false</font>|<font color="Blue">true</font>|
|123<br><span style="font-size:0.8em;color:#aaa;">数字</span>|<font color="Red">false</font>|NoMethodError|<font color="Red">false</font>|<font color="Blue">true</font>|
|""<br><span style="font-size:0.8em;color:#aaa;">空</span>|<font color="Red">false</font>|<font color="Blue">true</font>|<font color="Blue">true</font>|<font color="Red">false</font>|
|" "<br><span style="font-size:0.8em;color:#aaa;">半角スペース</span>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Blue">true</font>|<font color="Red">false</font>|
|"hoge"<br><span style="font-size:0.8em;color:#aaa;">文字列</span>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Blue">true</font>|
|[]<br><span style="font-size:0.8em;color:#aaa;">空配列</span>|<font color="Red">false</font>|<font color="Blue">true</font>|<font color="Blue">true</font>|<font color="Red">false</font>|
|["fuga", "piyo"]<br><span style="font-size:0.8em;color:#aaa;">配列(値あり)</span>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Blue">true</font>|
|{}<br><span style="font-size:0.8em;color:#aaa;">ハッシュ(空)</span>|<font color="Red">false</font>|<font color="Blue">true</font>|<font color="Blue">true</font>|<font color="Red">false</font>|
|{:key => value}<br><span style="font-size:0.8em;color:#aaa;">ハッシュ(値あり)</span>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Red">false</font>|<font color="Blue">true</font>|

### 気になった点・興味深い点

1. `empty?`は`nil`/`boolean`/`integer`の時に`NoMethodError`を返す  
→ `nil`/`boolean`/`integer`が弾かれてしまうということは、判定できるのは"文字列"か"配列"に限定されてしまうっぽいですね。
2. `false`の時に、`blank?`は`true`を返す  
→ `blank?`を`nil?`と`empty?`の合わせ技だと思って使っていると、ここの挙動の差に痛い目にあうかもですね。要注意です！
3. `" "(半角スペース)`の時は、`blank?`は`true`を返す  
→ `" "(半角スペース)`はblank（=からっぽ)という基準に合致するようですね。

## 結論

検証結果を見てわかる通り、非常にややこしい結果になりました。

if文などを書く時に、なんとなくで真偽判定メソッドを使っていると思わぬ値で予想に反する挙動を示して、バグを生んでしまう可能性があるので、十分に気をつける必要があります。`0`や`""（空）`や`" "(半角スペース)`などは特に注意する必要がありそうですね。

## さいごに

今回作った表は、忘れてしまった時に振り返り用として今後よく使うかもと思ったので、自分が見やすいように作りました。
ふとした時に参考になればいいなぁと思っています。