【Ruby】present?の使い方 | nil?、empty?、blank?との違いも覚えましょう

みなさんこんにちは!

今回の記事は、

悩みを抱えた人
・Rubyのpresent?メソッドの使い方が知りたい
・nil?、empty?、blank?メソッドとはどんな違いがあるの?
・presenceメソッドとの関係性は?

というお悩みを解決する記事になっています。


この記事の内容

・present?メソッドの使い方
・nil、文字列、数値、配列、ハッシュでのpresent?メソッドの動作検証
・nil?、empty?、blank?メソッドとの違い
・presenceメソッドの使い方


傍楽たろう
今回は、値の存在有無を判定するメソッドであるpresent?メソッドの利用方法をご紹介します。
また、データごとの動作検証や類似機能を持つ他のメソッドとの違いもサンプルコード付きで説明しますので、ぜひ参考にしてください。

なお、Rubyの魅力や特徴については以下の記事で詳しく解説していますので、こちらもぜひご覧くださいね。

おすすめ記事

みなさんこんにちは! 今回の記事は、 悩みを抱えた人 ・Rubyってどんなプログラミング言語なの?・Rubyを勉強すると将来役に立つかな?・Rubyのおすすめの学習方法が知りたい! というお悩みを解決する記事にな[…]

Rubyとは?その特徴や将来性、おすすめの学習方法まで網羅的にご紹介します

present?メソッドとは?

present?メソッドは、便利な機能がまとめられたライブラリである「Active Support」が提供するメソッドの1つです。

Rubyで定義できるすべてのデータをレシーバとして呼び出すことが可能で、変数の中身に値がセットされているかを判定します。

判定結果は論理値として返され、データがセットされていればtrue、そうでなければfalseを返します。

似た動きをするメソッドとして、nil?、empty?、blank?メソッドも存在しており、それぞれ以下の役割を持っています。

メソッド役割
nil?レシーバがnilかどうかを判定する(※レシーバがnilの場合にtrueを返却)
empty?レシーバの中身があるかどうかを判定する(※レシーバの中身がない場合にtrueを返却)
blank?nil?とempty?の両方の働きを持つ(※レシーバがnil或いはレシーバの中身がない場合にtrueを返却)
present?    blank?メソッドと逆の働きを持つ

present?メソッドの使用方法

present?メソッドをRubyで使用するためには、以下の手順を踏む必要があります。

  • 1. Active Supportをインストール
  • 2. Active Supportを読み込む

1. Active Supportをインストール

Rubyをインストールした時点ではActive Supportは導入されていないため、present?メソッドを利用する際には、あらかじめActive Supportをインストールしなければなりません(※Ruby on Railsではデフォルトで使用できます)。

Active Supportをインストールするには、コンソール上で以下のコマンドを入力します。

gem install activesupport

その後、コマンド「gem list」でActive Supportがインストール済みであるかを確認しましょう。インストールされていれば、コマンド結果に「activesupport」の文字列が出力されます。

2. Active Supportを読み込む

ただし、インストールしただけでは、present?メソッドは利用できません。

実際に利用するには、使用するファイル内でActive Supportを読み込む必要があります。

ただ、特に難しくはなく、以下の文字列を文頭に挿入すれば問題ありません。

require 'active_support/all'

present?メソッドが利用できるかを確かめるため、以下のソースコードを保存・実行してみましょう。

require 'active_support/all'

sample_val_1 = ""    # 空っぽのデータ 
sample_val_2 = "ABC" # 何かしらセットされているデータ

if sample_val_1.present?
  p "値が設定されています。"
else
  p "値が設定されていません。"
end

# 実行結果
=> "値が設定されていません。"

if sample_val_2.present?
  p "値が設定されています。"
else
  p "値が設定されていません。"
end

# 実行結果
=> "値が設定されています。"

上記のサンプルコードは、空文字が設定されている変数と文字列が設定されている変数に対して、present?メソッドを利用して値の有無を判定し、判定結果をコンソールに出力する処理を実装しています。

次の節では、present?メソッドの動作結果の違いについて、詳しく見ていきましょう。

present?メソッドの動作の詳細

present?メソッドは、変数の中身が以下のような状態の場合、falseを返します。

  • nil
  • false
  • 空白のみの文字列
  • 空文字列
  • 要素数0の配列
  • 要素数0のハッシュ

それぞれの値についてpresent?メソッドを呼び出し、実際にどのような値が返却されるかを見ていきましょう(※共通処理のため、require ‘active_support/all’ は省略しています)。

nilの判定

# オブジェクトとnil
val_1 = nil
val_2 = Object.new

p "nil   :" + val_1.present?.to_s
p "Object:" + val_2.present?.to_s

# 実行結果
"nil   :false"
"Object:true"

論理値の判定

# 論理値
val_3 = false
val_4 = true

p "false:" + val_3.present?.to_s
p "true :" + val_4.present?.to_s

# 実行結果
"false:false"
"true :true"

数値の判定

# 数値
val_5 = 0
val_6 = -1
val_7 = 1

p "0 :" + val_5.present?.to_s
p "-1:" + val_6.present?.to_s
p "1 :" + val_7.present?.to_s

# 実行結果
"0 :true"
"-1:true"
"1 :true"

文字列の判定

# 文字列
val_8  = ""
val_9  = " "
val_10 = " "
val_11 = " a "
val_12 = "abc" 

p "空文字  :" + val_8.present?.to_s
p "半角空白:" + val_9.present?.to_s
p "全角空白:" + val_10.present?.to_s
p "空白を含む文字列:" + val_11.present?.to_s
p "通常の文字列    :" + val_12.present?.to_s

# 実行結果
"空文字:false"
"半角空白:false"
"全角空白:false"
"空白を含む文字列:true"
"通常の文字列:true"

配列の判定

# 配列
val_13 = []
val_14 = [[], [], []]
val_15 = [1, 2, 3]

p "要素数0の配列:" + val_13.present?.to_s
p "要素数0の配列を含む配列:" + val_14.present?.to_s
p "通常の配列:" + val_15.present?.to_s

# 実行結果
"要素数0の配列:false"
"要素数0の配列を含む配列:true"
"通常の配列:true"

ハッシュの判定

# ハッシュ
val_16 = {}
val_17 = { 1=>{}, 2=>{}, 3=>{} }
val_18 = { 1=>"a", 2=>"b", 3=>"c" }

p "要素数0のハッシュ:" + val_16.present?.to_s
p "要素数0のハッシュを含むハッシュ:" + val_17.present?.to_s
p "通常のハッシュ:" + val_18.present?.to_s

# 実行結果
"要素数0のハッシュ:false"
"要素数0のハッシュを含むハッシュ:true"
"通常のハッシュ:true"

全体を通して、nilや空文字のように、意味のあるデータがセットされていないものについては、動作結果がtrueです。

例外として、論理値のfalseがセットされている場合はtrueを返しますので、この点は注意しておきましょう。

また、入れ子構造の配列やハッシュの場合は、レシーバとなっている変数の要素数が0であるか否かを判定するため、入れ子になっている配列やハッシュが空っぽであってもtrueが返されることに注意してください。

nil?、empty?、blank?メソッドとの違い

冒頭でもお伝えした通り、Rubyにはpresent?メソッドと同じように値の存在を検証するメソッドが他にも存在しています。

メソッド役割
nil?レシーバがnilかどうかを判定する(※レシーバがnilの場合にtrueを返却)
empty?レシーバの中身があるかどうかを判定する(※レシーバの中身がない場合にtrueを返却)
blank?nil?とempty?の両方の働きを持つ(※レシーバがnil或いはレシーバの中身がない場合にtrueを返却)
present?    blank?メソッドと逆の働きを持つ

それぞれ順に解説していきます。

nil?メソッド

まずは、Rubyで標準搭載されているnil?メソッドです。

nil?メソッドはその名の通り、変数の中身がnilであるか否かを判定する機能を持ちます。したがって、nilであればtrue、それ以外はどのような状態であってもfalseを返します。

以下に示すサンプルコードで動作結果を確認しましょう。

# オブジェクトとnil
val_1 = nil
val_2 = Object.new
val_3 = false
val_4  = ""
val_5  = " "
val_6 = "abc" 
val_7 = []
val_8 = [1, 2, 3]
val_9 = {}
val_10 = {1=>"a", 2=>"b", 3=>"c"}

# nilであればtrue
p "nil:" + val_1.nil?.to_s

# nil以外は全てfalse
p "Object:" + val_2.nil?.to_s
p "false:" + val_3.nil?.to_s
p "空文字:" + val_4.nil?.to_s
p "空白:" + val_5.nil?.to_s
p "文字列:" + val_6.nil?.to_s
p "空の配列:" + val_7.nil?.to_s
p "通常の配列:" + val_8.nil?.to_s
p "空のハッシュ:" + val_9.nil?.to_s
p "通常のハッシュ:" + val_10.nil?.to_s

# 実行結果
"nil:true"
"Object:false"
"false:false"
"空文字:false"
"空白:false"
"文字列:false"
"空の配列:false"
"通常の配列:false"
"空のハッシュ:false"
"通常のハッシュ:false"

empty?メソッド

2つ目は、Rubyの標準機能であるempty?メソッドです。

empty?メソッドは、Stringクラス・Arrayクラス・Hashクラスで利用できるメソッドです。

Stringクラスの場合は、変数の中身が空文字である場合にtrue、空白含めて何かしら文字が含まれている場合にfalseを戻り値とします。

ArrayクラスやHashクラスのempty?メソッドは、要素数が0であればtrue1以上あればfalseを返すのが基本的な動作です。

一方、変数が以下の場合のいずれかに当てはまる場合、empty?メソッドを呼び出そうとするとエラーになり、プログラムの実行が中断されます

  • nilである
  • Stringクラス・Arrayクラス・Hashクラス以外の種類である

値の判定がそもそもできないため、empty?メソッドを利用する際には注意が必要です。

サンプルコードと動作結果は以下の通りです。

val_1  = ""
val_2  = " "
val_3 = "abc" 
val_4 = []
val_5 = [1, 2, 3]
val_6 = {}
val_7 = {1=>"a", 2=>"b", 3=>"c"}

# 空文字や空白文字・要素数0の配列・ハッシュはtrue
p "空文字:" + val_1.empty?.to_s
p "空の配列:" + val_4.empty?.to_s
p "空のハッシュ:" + val_6.empty?.to_s

# 実行結果
"空文字:true"
"空の配列:true"
"空のハッシュ:true"

# 何かしら値がセットされている場合はfalse
p "空白:" + val_2.empty?.to_s
p "文字列:" + val_3.empty?.to_s
p "通常の配列:" + val_5.empty?.to_s
p "通常のハッシュ:" + val_7.empty?.to_s

# 実行結果
"空白:false"
"文字列:false"
"通常の配列:false"
"通常のハッシュ:false"

blank?メソッド

3つ目は、Active Supportが提供するblank?メソッドです。

blank?メソッドは、present?メソッドの動作結果とは全く逆の結果を返します。つまり、nilや空文字がセットされている場合にtrue、そうでない場合にfalseを返すのが基本的な動作です。

以下のサンプルコードで、結果がお互いに逆になっていることを確認しましょう。

require 'active_support/all'
 
# オブジェクトとnil
val_1 = nil
val_2 = Object.new

p "nil  blank:" + val_1.blank?.to_s + " / present:" + val_1.present?.to_s
p "Object  blank:" + val_2.blank?.to_s + " / present:" + val_2.present?.to_s

# 実行結果
"nil blank:true / present:false"
"Object blank:false / present:true"

# 文字
val_3  = ""
val_4 = "abc" 

p "空文字  blank:" + val_3.blank?.to_s + " / present:" + val_3.present?.to_s
p "通常の文字列  blank:" + val_4.blank?.to_s + " / present:" + val_4.present?.to_s

# 実行結果
"空文字 blank:true / present:false"
"通常の文字列 blank:false / present:true"

# 配列
val_5 = []
val_6 = [[], [], []]
val_7 = [1, 2, 3]

p "要素数0の配列:" + val_5.blank?.to_s + " / present:" + val_5.present?.to_s
p "要素数0の配列を含む配列:" + val_6.blank?.to_s + " / present:" + val_6.present?.to_s
p "通常の配列:"  + val_7.blank?.to_s + " / present:" + val_7.present?.to_s

# 実行結果
"要素数0の配列:true / present:false"
"要素数0の配列を含む配列:false / present:true"
"通常の配列:false / present:true"

上記の通り、present?メソッドと逆の値が返却されているのがお分かりいただけたかと思います。

presenceメソッドで条件分岐をリファクタリング

さて、ここまでpresent?メソッドの使い方やその他の類似メソッドとの違いを解説してきましたが、このpresent?メソッドをもう少し進化させたpresenceメソッドというものも存在します。

presenceメソッドは、present?メソッドの返り値がtrueであればそのレシーバを、falseであればnilを返却する役割を持ちます。

object = "オブジェクト"
object.presence
=> "オブジェクト"

object = ""
object.presence
=> nil

このpresenceメソッドは、以下のように ||演算子を使った条件分岐を実装する際に非常に役立ちます。

以下では、objectが存在している場合にはobjectを返し、存在しない場合には「objectは存在しません」と返す処理を実装しようとしています。

# present?メソッドを使う場合
object.present? ? object : "objectは存在しません"

# presenceメソッドを使う場合
object.presence || "objectは存在しません"

ただし、このpresenceメソッドもRailsの拡張機能であり、present?メソッドと同様にActive Supportを読み込まなければならないので、その点は覚えておいてくださいね。

お仕事の途中ですが、少し一休みして、転職独立について考えてみませんか🙌?

現役エンジニアが選ぶおすすめの転職エージェント11選【成功談・失敗談もあります】

レバテックフリーランスの評判ってどう?【現役エンジニアが徹底解説します】

MidWorks(ミッドワークス)の評判ってどう?【現役エンジニアが徹底解説します】

日々の業務に追われて自分を見失わないよう、
定期的にキャリアを振り返るようにしておきましょう🤲

最後に

さて、ここまでRubyのpresent?メソッドの使い方について解説してきましたがいかがでしたか?

Rubyの標準メソッドではないため、Active Supportを読み込む必要はありますが、特に手間も掛からず、使い方自体もとてもシンプルなメソッドになっています。

Railsでは特に追加の設定なく使用することができるため、そちらで馴染みがあった方も多いのではないでしょうか?

今回の記事でしっかりとマスターして、今後の開発でも積極的に使っていってくださいね。

このブログを通じて少しでも「傍(はた)を楽(らく)にする」ことができていれば嬉しく思います。

最後まで読んで頂きありがとうございました。