Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

RubyとRailsの#nil?、#empty?、#blank?、#present?の違いを徹底解説

RubyとRailsには、値の存在確認やオブジェクトの状態チェックに使えるメソッドがいくつかあります。Rubyには#nil?#empty?が用意されており、RailsのActiveSupportはさらに#blank?#present?を追加しています。これらはそれぞれ異なる挙動をするため、各メソッドがどのようにデータを評価するのかを理解しておくことが重要です。誤ったメソッドを選ぶと、予期しない結果やバグにつながる可能性があります。

この記事では、これら4つのメソッドについて知識を整理します。それぞれのメソッドがどのような条件でtrue/falseを返すのか、またどの種類のオブジェクトに対して使えるのかを(再)学びましょう。記事の最後には、ブックマークしておくと便利なチートシートもご用意しています!

#nil?とは

#nil?はRubyのObjectクラスに定義されたメソッドです。すべてのクラスはこのクラスを継承しているため、#nil?はあらゆるオブジェクトに対して使用できます。nilNilClassクラスのインスタンス)に対してはtrueを返し、それ以外のすべての値に対してはfalseを返します。

nil.nil?
=> true

true.nil?
=> false

5.nil?
=> false

"".nil?
=> false

[].nil?
=> false

#empty?とは

#empty?は、文字列・配列・ハッシュ・セットに対して使用できるメソッドで、オブジェクトの長さがゼロの場合にtrueを返します。

文字列の場合

空文字列に対してはtrueを返します。

"".empty?
=> true

ただし注意点があります。空白文字も立派な「1文字」であるため、空白のみを含む文字列に#empty?を使うとfalseが返されます。このため、テキストのバリデーションには必ずしも最適なメソッドとは言えません。例えば、ユーザー入力の検証にこのメソッドだけを使っていると、空白しか含まない入力をそのまま処理してしまう恐れがあります。

" ".empty?
=> false

"\t\n".empty?
=> false

配列・ハッシュ・セットの場合

要素がひとつもない場合にtrueを返します。

[].empty?
=> true

{}.empty?
=> true

require 'set'
Set.new.empty?
=> true

NoMethodErrorに注意

#empty?nilや、このメソッドを定義していない他のクラスのオブジェクトに対して呼び出すと、NoMethodError例外が発生します。そのため、データチェックに使う場合は、プログラムがクラッシュしないように事前のチェックを組み込む必要があります。

if !my_var.nil? && !my_var.empty?
  # my_var を安全に使用できる
end

より良い方法として、Railsの#blank?メソッドを使う手があります。次はこれを見ていきましょう。

#blank?とは

#blank?はRails(ActiveSupport)が提供するメソッドで、任意のオブジェクトに対して動作します。

文字列の場合

空文字列に加えて、空白文字のみを含む文字列に対してもtrueを返します。

"".blank?
=> true

" ".blank?
=> true

"\n\t".blank?
=> true

配列・ハッシュ・セットの場合

#empty?と同様に、要素がなければtrueを返します。

[].blank?
=> true

{}.blank?
=> true

Set.new.blank?
=> true

[nil].blank?
=> false

["", ""].blank?
=> false

person = {:firstName => "John", :lastName => "Doe"}
person.blank?
=> false

真偽値の場合

trueに対してはfalseを返し、偽と評価される値(つまりnilfalse)に対してはtrueを返します。

true.blank?
=> false

false.blank?
=> true

nil.blank?
=> true

ご覧のとおり、#blank?はすべてのオブジェクトで利用可能なため、一部のオブジェクトに対してNoMethodErrorが発生することはありません。さらに、空白のみの文字列も正しく判定できます。データのバリデーションにおいては、#empty?よりも#blank?の方が安全で便利だと言えます。

#present?とは

#present?もRailsのメソッドで、#blank?のちょうど逆の結果を返します。

!my_var.blank? == my_var.present?
=> true

以下にいくつか例を示します。

"".present?
=> false

" ".present?
=> false

[].present?
=> false

nil.present?
=> false

true.present?
=> true

false.present?
=> false

{}.present?
=> false

person = {:firstName => "John", :lastName => "Doe"}
person.present?
=> true

5.present?
=> true

#blank?と同じ理由から、バリデーション用途では#empty?よりもこちらの方が優れた選択肢となります。

まとめ:チートシートで一目でわかる違い

これらのメソッド名は紛らわしく混乱しやすいため、ブックマークしておくと便利なチートシートを用意しました。

対象の値#nil?#empty?#blank?#present?
5falseNoMethodErrorfalsetrue
""falsetruetruefalse
" "falsefalsetruefalse
"\t\n"falsefalsetruefalse
[]falsetruetruefalse
["a"]falsefalsefalsetrue
{}falsetruetruefalse
{a: "b"}falsefalsefalsetrue
Set.newfalsetruetruefalse
niltrueNoMethodErrortruefalse
truefalseNoMethodErrorfalsetrue
falsefalseNoMethodErrortruefalse

当然ながら、#nil?#empty?#blank?#present?のどれを選ぶべきかは状況によって異なります。例えば、ユーザーの名前が登録されているかどうかを確認して呼びかけたいようなケースでは、#present?が適しているでしょう。一方で、#blank?#present?はすべてのオブジェクトに対してbooleanを返すため、値の型が想定と違っていてもエラーが発生せず、コード中のバグを見逃してしまう可能性がある点には注意が必要です。

Rubyでの値チェックに関する知識の再確認になれば幸いです。ご質問やコメントがあれば、お気軽に@AppSignalまでお寄せください。

  1. ビットコインとイーサリアムの違いを徹底解説!投資前に知っておきたい3つのポイント

    2017年は間違いなく暗号資産(仮想通貨)の年となりました。その後、価格は下落したものの、特に主要通貨への関心は衰えていません。最も人気のある2つの通貨であるビットコインとイーサリアムは、この年、劇的な価格上昇を見せました。ビットコインは1,000ドル未満から約20,000ドル近くまで、イーサリアムは10ドル未満から1,300ドル超まで急騰しています。暗号資産への投資に関心がある方のために、ここではビットコインとイーサリアムの主な違いについてわかりやすく解説します。 1. ビットコインは第1世代、イーサリアムは第2世代 ビットコインは、一般の人々の注目を集めた最初の主要な暗号資産です。ある

  2. SpotifyとApple Musicの違いを徹底比較|知っておきたい6つのポイント

    音楽が好きな方なら、数ある音楽ストリーミングサービスの中でも特に人気の高い「Spotify」と「Apple Music」をご存じでしょう。どちらも月額プランに加入することで、膨大な楽曲ライブラリを無制限に楽しめるサブスクリプション型サービスです。しかし、この2つのサービスには注目すべき違いが数多くあります。どちらか一方への加入を検討しているなら、それぞれの特徴を把握しておくことで、自分の聴き方やニーズに合ったプラットフォームを選びやすくなります。ここでは、SpotifyとApple Musicの主な6つの違いをわかりやすく解説します。1. 収録コンテンツの量音楽ストリーミングサービスを選ぶうえ