Ruby on Rails

【Rails】nil? empty? blank? present?メソッドの使い分け

おはようございます。また今日から一週間が始まりましたが、頑張っていきましょう。
さて今回はタイトルのようによく混乱してしまうnil?empty?メソッドなどの挙動について細かくみていきたいと思います。これを曖昧なまま実務で本番のコードを触ってしまい、バグを生んでしまい反省からこの記事を書いています。

nil?メソッド

レシーバがnilであればtrueを返すメソッドです。Objectクラスに属しています。

nil.nil?
=> true

"hoge".nil?
=> false

false.nil?
=> false

"".nil?
=> false

" ".nil?
=> false

{}.nil?
=> false

[].nil?
=> false

見ての通りnil(NilClass)でない限りfalseになります。

empty?メソッド

中身が空かどうかを判別するメソッドです。StringクラスとArrayクラスに属しています。

"".empty?
=> true

"hoge".empty?
=> false

" ".empty?
=> false

[].empty?
=> true

{}.empty?
=> true

nil.empty?
NoMethodError: undefined method `empty?' for nil:NilClass

false.empty?
NoMethodError: undefined method `empty?' for false:FalseClass

0.empty?
NoMethodError: undefined method `empty?' for 0:Integer

注意したい点として、あくまで空かどうかを判別するメソッドなので、nilだったりfalseの場合はNoMethodErrorになるという点です。やってしまいがちな記述として以下のような例が挙げられます。

user = User.new
=> #<User:0x00007ff388429fe0 id: nil, email: nil, password_digest: nil, created_at: nil, updated_at: nil>
user.email.nil?
=> true

#emailの中身はnilなので、empty?は使えない
user.email.empty?
NoMethodError: undefined method `empty?' for nil:NilClass

さかい
さかい
empty?メソッドでは数字が渡ってきたときに例外を返してしまうなど使い勝手が悪いので、blank?メソッドを使うことが多いよ

blank?メソッド

nilの場合も""{}の場合もtrueを返したいときに使います。ただし、falseでもtrueが返るので注意。僕はこれでバグを生んでしまいました。こちらはRailsで拡張されて使えるメソッドです。

"".blank?
=> true

" ".blank?
=> true

nil.blank?
=> true

false.blank?
=> true

"hoge".blank?
=> false

{}.blank?
=> true

[].blank?
=> true

3.blank?
=> false

0.blank?
=> false

nil""の場合はもちろん、" "falseでもtrueが返っています。開発で真偽値の判定をするときはこの挙動を頭に入れてどのメソッドを使うか慎重に判断する必要があります。

present?メソッド

present?メソッドは存在するかどうかを判別するメソッドです。!blankメソッドと同じ挙動をします。こちらもfalseではfalseが返るので注意が必要です。

"".present?
=> false

" ".present?
=> false

nil.present?
=> false

false.present?
=> false

{}.present?
=> false

[].present?
=> false

0.present?
=> true

もぐくん
もぐくん
blankメソッドと逆だね

presenceメソッド

最後に上のメソッドに関連して、便利だなと思ったpresenceメソッドについて紹介していきたいと思います。presenceメソッドはその名の通りで、present?メソッドでtrueならばレシーバを返し、それ以外ならnilを返します。

"".presence
=> nil
nil.presence
=> nil
{}.presence
=> nil
0.presence
=> 0
"hoge".presence
=> "hoge"

さいごに

いかがだったでしょうか。真偽値判定に使える様々なメソッドを紹介してきました。まだ経験が浅いですが僕の見てきた中ではnil?やblank?メソッドやpresent?メソッドが登場する機会としては多いかなと肌感覚としてあります。

これらの挙動を理解せずに実装し、バグを生んでしまった僕みたいにならないようにしっかり理解しておくといいと思います。
ここまで読んでいただきありがとうございました!

ABOUT ME
sakai
三重出身の28歳。前職はメーカーで働いていて、プログラミングスクールに通って未経験からWeb業界に転職しました。Railsをメインで使っていて、AWSも少しできます。音楽を聞くこととYoutubeを見るのが好きです。最近はへきトラ劇場にハマってます