【Ruby】nil判定の方法およびnilの概念についてご紹介します!【初心者向け】

  • 2020年4月11日
  • 2021年12月19日
  • Ruby

今回は、nil判定の方法nilの概念、そしてnilが原因のエラーの回避方法についてご紹介させていただきます。

開発を進める中でnilは厄介なオブジェクトですが、今回ご紹介する内容を頭に入れておけば怖いものはありません。

そんな悩みをお持ちの方々に向けて分かりやすく簡潔にご説明していきますので、ぜひ最後まで読んでみてください。

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

おすすめ記事

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

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

フリーランス案件を探すならこのエージェント!

運営会社 レバテック株式会社 株式会社Branding Engineer 株式会社Hajimari
対応エリア 東京・神奈川・埼玉・千葉
大阪・兵庫・京都・愛知・福岡
東京・神奈川・埼玉・千葉
大阪・兵庫・京都・奈良・和歌山・滋賀
東京・神奈川・埼玉・千葉
茨城・大阪・兵庫・福岡
案件数 約28,000件 約3,300件 約4,200件
平均単価 68.2万円 72.2万円
最高月収 145万円 200万円 176万円
支払いサイト 15日(月末締め翌月15日支払い) 20日
手数料(中間マージン) 非公開 非公開
※実質20%
非公開
特徴高単価な案件が多い
福利厚生サービスが受けられる
・首都圏の案件が中心
給与保証制度で安定した収入を得られる
・税務処理のサポートあり
・マージン率は実質20%
週2/週3の案件が多い
在宅/リモート案件が多い
・スタートアップ企業やベンチャー企業の案件が多い
紹介企業例 ・株式会社Gunosy
・株式会社バンダイナムコホールディングス
・株式会社ユーザベース
・Sansan株式会社
・株式会社一休
・株式会社FiNC Technologies など
・クックパッド株式会社
・株式会社カオナビ
・株式会社Kaizen Platform など
説明記事
公式サイト


転職を考えているならこのエージェント!

運営会社 レバテック株式会社 株式会社Branding Engineer 株式会社リブセンス
対応エリア 東京・神奈川・埼玉・千葉
大阪・兵庫・京都・愛知・福岡
東京・神奈川・埼玉・千葉
大阪・兵庫・京都・奈良・和歌山・滋賀
東京・神奈川・埼玉・千葉
茨城・大阪・兵庫・福岡
案件数 約13,000件 約800件
※非公開求人が多い

※ドラフト制のため、対象外
年齢層 20代:◎
30代:〇
40代:〇
20代:〇
30代:〇
40代:△
20代:〇
30代:〇
40代:〇
特徴エンジニア・デザイナーを専門としている
・カウンセリングに時間をかける
年収アップ率60%の実績
IT/Web/ゲーム業界専門の転職エージェント
・業界経験者がキャリアコンサルタントを務める
・丁寧なカウンセリングで入社後の離職率1%以下を実現
ドラフト制による採用を叶える特殊なサービス
スキル・経験重視で評価してもらえる
・他エンジニアの入札結果を見ることで
自分の市場価値が分かる
紹介企業例 ・サイボウズ株式会社
・株式会社サイバーエージェント
・Chatwork株式会社 など
・DMM.com
・Money Forward
・SmartHR など
・メルカリ
・ZOZOテクノロジーズ
・freee など
説明記事
公式サイト



nilとは

まず初めに、nilとは何かについてご説明させていただきますね。

nilとは、簡単に言うと、「存在しない」という意味です。

この説明を聞いた段階では、「なるほど、""とか[]とか、0なんかがnilということなんだな」と思われる方も多いかと思いますが、Ruby(というよりもプログラミング言語)はこれらを「存在している」ものと解釈します

実際に確かめてみると以下のような結果が得られます。
(※「nil?」メソッドは、nilかどうかを確認するメソッドです。詳しくは次章でご説明しますね。)

irb(main):001:0> "".nil?
=> false
irb(main):002:0> [].nil?
=> false
irb(main):003:0> 0.nil?
=> false

このように、「中身は空だがオブジェクトとしては存在している」ものとして解釈されます。

実際の開発では、想像以上にこのnilが出てきてしまい、思わぬエラーを発生させてしまいますので、このnilをどのように回避していくかが非常に重要になってくるのです。

それでは早速、オブジェクトがnilかどうかを判定する方法を見てきましょう。

Rubyでnil判定をする方法まとめ

Rubyを使ってnil判定をする方法としては以下の4つが挙げられます。

  • 1. nil?
  • 2. empty?
  • 3. blank?
  • 4. present?

それぞれ順を追ってご説明させていただきますね。

Rubyでnil判定をする方法その1 nil?メソッド

まずご紹介するのは、「nil?」メソッドです。

先ほど少しご紹介しましたが、nil?メソッドを使用すると、そのオブジェクトがnilかどうかを判定することができ、戻り値はBoolean値(true/false)になります

irb(main):001:0> "".nil?
=> false
irb(main):002:0> [].nil?
=> false
irb(main):003:0> test = nil
irb(main):004:0> test.nil?
=> true

Rubyでnil判定をする方法その2 empty?メソッド

続いてご紹介するのは、「empty?」メソッドです。

empty?メソッドは厳密に言うとnilを判定するものではなく、オブジェクトが空かどうかを確認するためのメソッドになります。

irb(main):001:0> "".empty?
=> true
irb(main):002:0> [].empty?
=> true
irb(main):003:0> "Ruby".empty?
=> false
irb(main):004:0> ["Ruby", "Rails"].empty?
=> false

このように、空の文字列配列に対してempty?メソッドを使用するとtrueが返ってきているのがお分かりいただけるかと思います。

他方で、「中身が空かどうかを確認する」ということは、少なくとも中身を入れるための「入れ物」が必要ということになり、nilやBoolean値、或いは数字に対してempty?メソッドを呼び出すとNoMethodErrorが発生してしまいますのでご注意くださいね。

irb(main):001:0> nil.empty?
=> NoMethodError (undefined method `empty?' for nil:NilClass)
irb(main):002:0> true.empty?
=> NoMethodError (undefined method `empty?' for true:TrueClass)
irb(main):003:0> 0.empty?
=> NoMethodError (undefined method `empty?' for 0:Integer)

Rubyでnil判定をする方法その3 blank?メソッド

続いてご紹介するのは、「blank?」メソッドです。

blank?メソッドですが、Railsで拡張されたメソッドのため、Ruby単体では使用することはできません(NoMethodErrorが発生します)。

ただし、Rubyを用いて開発する際には多くの場合Railsを使いますので、こちらのメソッドもぜひ覚えておきましょう。

blank?メソッドは、簡単に言うと、これまでのnil?メソッドとempty?メソッドの機能を組み合わせたメソッドです。

つまり、nilか中身が空のオブジェクトの場合にtrueを返してくれます

[1] pry(main)> nil.blank?
=> true
[2] pry(main)> [].blank?
=> true
[3] pry(main)> "".blank?
=> true
[4] pry(main)> false.blank?
=> true
[5] pry(main)> 0.blank?
=> false

empty?メソッドだとnilチェックができなかった(NoMethodErrorが発生していた)ので、とても便利になりましたよね。

なお、あまり出くわす機会はないとは思いますが、falseに対してblank?メソッドを使用した場合にもtrueが返ってきますので、ご注意くださいね。

Rubyでnil判定をする方法その4 present?メソッド

最後にご紹介するのは、「present?」メソッドです。

こちらもblank?メソッドと同様にRailsにて拡張されたメソッドです。

その機能としては、blank?メソッドの反対、つまりnilか中身が空のオブジェクトの場合にはfalseを返します

[1] pry(main)> nil.present?
=> false
[2] pry(main)> [].present?
=> false
[3] pry(main)> "".present?
=> false
[4] pry(main)> false.present?
=> false
[5] pry(main)> 0.present?
=> true

nil判定をした際の結果まとめ

さて、ここまでRuby/Railsを使ってnil判定する方法を見てきましたが、「結局のところどれを使ったらいいの?」という疑問をお持ちの方も多いかと思います。

そんな方々に向けて、私の方で様々なケースを試し、以下の表の通りまとめてみましたので、ど忘れしたり迷ってしまった際にはぜひこちらをご参照ください。
(※左端の列には「対象となるオブジェクト(レシーバ)」を記載し、4つのメソッドの戻り値をそれぞれ記載しています)

nil?empty?blank?present?
niltrueNoMethodErrortruefalse
数字(0も含む)falseNoMethodErrorfalsetrue
“”falsetruetruefalse
” “(半角/全角スペース)falsefalsetruefalse
{}falsetruetruefalse
[]falsetruetruefalse
truefalseNoMethodErrorfalsetrue
falsefalseNoMethodErrortruefalse

開発の中でnilを回避する方法

さて、続いては、実際に開発する中でいかにしてnilによるエラーを防いでいけば良いかということをご紹介していきます。

ではまず、nilによってどのようなエラーが発生するかを見ておきましょう。

nilが原因で発生するエラーはズバリNoMethodErrorです。

irb(main):001:0> nil.empty?
=> NoMethodError (undefined method `empty?' for nil:NilClass)

上記の通り、nilNilClassのインスタンスであり、そのNilClassにメソッドが登録されていないためにこのエラーが発生してしまうのです。

「え、nilが使えるメソッドってそもそもあるの?」と思われた方、実は結構な数のメソッドが存在しているのです。

気になる方は、nil.methodsと調べてみてください。まあまあびっくりされると思います。

さて、少し話が脱線しましたが、nilによるエラー(NoMethodError)を防ぐためには主に以下の2つの手段があるかと思います。

  • 1. そもそもnilを作らない
  • 2. nilに対してメソッドを呼び出してもエラーを発生させないようにする

まずは、最初の「そもそもnilを作らない」という方法をご紹介します。
(※こうした「nilを回避する」方法は「nilガード」とも呼ばれます)

Rubyでnilを回避する方法その1 ||(パイプ演算子)=を使用する

そもそも「nilを作らない」ためには、||(パイプ演算子)=を使用します

# オブジェクトがnilの場合
irb(main):001:0> language = nil
irb(main):002:0> language ||= "Ruby"
irb(main):003:0> language
=> "Ruby"

# オブジェクトがnilではない場合
irb(main):001:0> language = "Rails"
irb(main):002:0> language ||= "Ruby"
irb(main):003:0> language
=> "Rails"

上記のように、||(パイプ演算子)=を使用することで、オブジェクトがnilの場合にのみ値を代入することができます

上記に構文は実際の開発の中でも頻繁に使用しますので、この機会にぜひ覚えておいてくださいね。

Rubyでnilを回避する方法その2 &.(ぼっち演算子)

ここからは、「nilに対してメソッドを呼び出してもエラーを発生させないようにする」方法を見ていきます。

まず最初は、「&.(ぼっち演算子)」になります。この「ぼっち」ですが、見た目が一人ぼっちの人のように見えることからこのように呼ばれています。

この&.(ぼっち演算子)を使用すると、レシーバがnilの場合であってもNoMethodErrorが発生しないようになります

# &.(ぼっち演算子)を使用しない場合
irb(main):001:0> nil.empty?
=> NoMethodError (undefined method `empty?' for nil:NilClass)

# &.(ぼっち演算子)を使用した場合
irb(main):001:0> nil&.empty?
=> nil

ただし、レシーバがnilではなく且つそのレシーバが持っていないメソッドを呼び出してしまうとNoMethodErrorが発生してしまいます

irb(main):001:0> nil&.empty?
=> nil
irb(main):002:0> 100&.empty?
=> NoMethodError (undefined method `empty?' for 100:Integer)
irb(main):003:0> "Ruby"&.empty?
=> false

上記を踏まえると、レシーバのクラスが確定していない場合(「文字列」も「数字」も入る可能性のある場合 など)には、&.(ぼっち演算子)を使用してもまだNoMethodErrorが発生する可能性が残ってしまうということになります。

Rubyでnilを回避する方法その3 tryメソッド

このような状況を打破するために登場したのが、「try」メソッドです。

この「try」メソッドは、&.(ぼっち演算子)とは異なり、「レシーバが持っていないメソッド」を呼び出してもNoMethodErrorが発生しませんnilを返します)。

[1] pry(main)> nil.try(:empty?)
=> nil
[2] pry(main)> 100.try(:empty?)
=> nil
[3] pry(main)> "Ruby".try(:empty?)
=> false

ただし、こちらも上記でご説明した「blank?」メソッドや「present?」メソッドと同様にRailsで拡張されたメソッドですので、Ruby単体の環境では動きませんのでご注意くださいね。

でも、何でもかんでもtryするのはやめておきましょう

ここまでを踏まえると、「とりあえずtryを使っておけば安全だな」と思われる方もいらっしゃると思いますが、実際の開発ではあまり多用しないようにしましょう

というのも、「オブジェクトがnilの場合」や「メソッドが存在しない場合」にエラーが発生しないということにより、思わぬバグに気づくことができない(バグを握り潰してしまう)のです。

特に、後者の「メソッドが存在しない場合」については、そもそも期待していたものとは異なるクラスのオブジェクトが返ってきているということですので、この場合には実装自体を見直した方がよいです。

もちろん、これらの要素を把握した上でなおtryを使用するということであれば問題はありませんが、「とにかくエラーをなくそう」としてtryを連発してしまうのだけは避けましょうね

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

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

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

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

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

最後に

さて、ここまで、nil判定の方法やnilの概念、そしてnilの回避方法についてご紹介してきましたがいかがでしたか?

nilは絶対悪のようなイメージを持ってらした方もいらっしゃると思いますが、決してそんなことはありません。

実際の開発を進める中で必ずと言ってよいほどnilは現れてきますので、「nilを減らす」ことも大事ですが、「出てきたnilにどのように対応するか」ということも重要になってきます。

今回ご紹介したメソッドなどを活用し、なるべくエラーの発生しない綺麗なコードを書いていってくださいね。

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

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