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

  • 2020年4月11日
  • 2021年10月15日
  • Ruby

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

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

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

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

おすすめ記事

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

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

レバテックフリーランス … 業界最大級の案件数業界トップクラスの高単価報酬を誇る最大手のサービスです。実績豊富なコーディネーターが丁寧な対応をしてくれるため、案件の無理な提案はありません。フリーランスで生きていくためにはまず登録しておきましょう。
MidWorks … フリーランス賠償責任保障生命保険の折半など、フリーランスでありながらも正社員並みの保障を受けられるのが特徴です。また、経験豊富なキャリアコンサルタントによる手厚いサポートも受けられるため、安定したフリーランス生活を送りたい方には特におすすめのサービスです。
ポテパンフリーランス … IT業界・技術に詳しいコンサルタントが担当してくれるため、こちらの要望をきちんと理解した上で案件を紹介してくれます。また、案件情報のみならず、フリーランスのイロハについても教えてくれるため、フリーランスとして初めて活動される方には特におすすめのサービスです。

レバテックキャリア … ITエンジニアが利用したい転職エージェントNo.1にも選ばれており、年収600万円以上のハイクラス求人を5,000件以上も保有しています。エンジニアが転職を考えた時にまず初めに登録しておくべきサービスです。
Tech Stars Agent … Tech Stars Agentでは、担当エージェントが全員エンジニア出身のため、スキルやキャリアを見据えたきめ細かな転職支援が受けられます。運営元の株式会社Branding Engineerは、独立支援サービス「MidWorks」も展開しているため、独立を視野に入れたサポートも受けられます
転職ドラフト … 年収UP率93.8%/平均年収UP額126万円と圧倒的な年収UP率を誇るイベント型のエンジニア向け 転職サービスです。毎月1回開催され、厳選された優良IT/Web系企業約150社からダイレクトスカウトを受け取ることができます。年収アップを目指す方は登録必須です。


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にどのように対応するか」ということも重要になってきます。

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

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

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