Ruby
Rails
RubyOnRails

Ruby on Railsのオブジェクト存在チェック4種

More than 1 year has passed since last update.

Ruby on Railsには、オブジェクトの存在チェックに以下の4つがあります。

  • nil?
  • empty?
  • blank?
  • present?

では、それぞれ簡単に見ていきましょう。

そもそもオブジェクトって何?

オブジェクトというのは「箱」みたいなものです。

箱がなければ、中に何も入れられませんし、
箱があれば、中に何か入れられますよね。
(「何か」は、プログラムの世界だと変数やらオブジェクトやらです。)

なので「オブジェクトの存在チェック」というのは、以下のようなイメージになります。

  • 箱そのものはある?
  • 箱はあるけど、中身ある?

nil?

nilは、日本語で「何もない」という意味です。
使い方はこう。

if obj.nil?
  # 処理
end

つまり、「箱そのものが存在しますか?」という事になります。

empty?

emptyは、日本語で「空の」という意味です。
使い方はこう。

if obj.empty?
  # 処理
end

つまり、「箱の中身は空ですか?」という事になります。

blank?

blankは、日本語で「白紙の」「何もない」という意味があります。
ご察しの通り、nilblankの組み合わせです。(白紙=紙はあるのに何も書かれてない、何もない=そもそも紙もない、というイメージ)
使い方はこう。

if obj.blank?
  # 処理
end

つまり、「箱そのものが存在しますか?存在してたとしても空ですか?」という事になります。
なので、以下と同義です。

if obj.nil? || obj.empty?
  # 処理
end

補足

判定する際に、順番は大切です。
「箱の中身は空ですか?または箱そのものが存在しますか?」と判定してしまうと、
「箱の中身を問われても、そもそも箱そのものが存在しねえわボケ」と、errorが吐かれます。(いわゆるヌルポ)

人間だと文章全体を見て答えてくれますが、
機械は忖度では動いてくれません.....

present?

presentは、日本語で「現在の」「存在している」という意味があります。
使い方はこう。

if obj.present?
  # 処理
end

つまり、「箱そのものが存在していて、かつ、中身もありますか?」という事になります。

「あれ? 『存在している』って意味なんだから、箱が存在しているかどうかだけじゃないの???」
という声が聞こえてきそうですが、僕もそう思ってました。
調べても分からなかったので、僕自身の覚え方で申し訳ないのですが、「present=プレゼント=箱の中に何か入ってるはず」といった感じで覚えてます。
(present=プレゼントじゃないですけど、覚え方だからどうでもいいのです。)

応用

判定条件は、接頭辞に!を付ける事で結果を反転させられます。
例えばこんな感じ。

obj = nil

p obj.nil?  # trueと出力される

p !obj.nil? # trueという判定が覆されて、falseと出力される

という事は、以下は同義という事になります。

#箱そのものがない?
obj.nil?
obj.blank?
!obj.present

#箱はあるけど、中身がない?
obj.blank?
!obj.nil && obj.empty?
!obj.present?

#箱もあるし、中身もある?
obj.present
!obj.blank?
!obj.nil? && !obj.empty?

注意点

  • nil?empty?は、Ruby標準のメソッドです。
  • blank?present?は、Railsで拡張されたメソッドです
    • つまり、
    • Ruby単体で使っている場合は、blank?present?は使えない!!!!!
      • その時は、おとなしくnil?empty?を駆使して頑張ってください。さっきの「応用」です。ファイト。

追記 2017-10-26

@jkr_2255 さんからご指摘いただきました。ありがとうございます。
コメントにもあります通り、blank?は、スペースのみ、また、タブのみの場合もtrueを返却します。
ちなみに、empty?は、スペースのみ、また、タブのみの場合はfalseを返却します。
つまり、
  blank?君「実体のないものはない。」
  empty?ちゃん「実体はないけど、あるって言われたらある。」
みたいな感じ。
empty?ちゃんは哲学っぽいですね。(意味不明)