はじめに
実務でコードを書いているときに次の3つの違いを先輩に問われたことがありました。
- nil?
- empty?
- blank?
どれもレシーバに値ががない状態?であることを確認するときに使っていました。
私自身よく考えずに使っていたので詳しく調べてみることにしましたので備忘録として残します。
間違いや補足がありましたら教えてください。
環境
Ruby 2.7.1
Rails 6.0.5
3つの違いとは
nil?
Rubyのドキュメントによると次の通りです。
レシーバが nil であれば真を返します。
レシーバ自体が存在しない場合、つまりnilであればtrueを返します。
※追記
nil は何かが存在しないことを表すために用いられるオブジェクトです。
レシーバが存在しないということはあり得ないというご指摘をいただきましたので追記です。
empty?
Rubyのドキュメントによると次の通りです。
文字列が空 (つまり長さ 0) の時、真を返します。
nilとは違い、空の場合にtrueとなります。
@scivola さんよりご指摘いただいています。
empty?メソッドにも様々な種類があるようで、詳しくはコメント欄をご覧ください。
blank?
@koki_73 さん、@scivola さんよりご指摘いただきましたので追記です。
Rails公式によると
An object is blank if it's false, empty, or a whitespace string. For example, nil, '', ' ', [], {}, and false are all blank.
直訳すると
オブジェクトが false、empty、または空白文字列である場合、blankとなります。例えば、nil, '', '', [], {}, false はすべてblankです。
と記されています。
おお便利。ただ理解して使わないとバグの原因にもなりそう。
blank?はつまりnil?とempty?を一緒に確認して、どちらかがtrueであればtrueを返すということですね!
falseであればnil?メソッドであればfalseを返し、empty?であればNoMethodErrorを返します。
しかし、blank?ではtrueとなりますね。
今回も自分の目で確かめてみようと思います。
やってみた
一方の変数にnil1を、もう一方の変数には""を代入します。
nil_str = nil
empty_str = ""
それぞれメソッドを試してみます。
nil?の場合
nil?の場合を見てみます。
nilの値が代入されたレシーバのみtrueを返しました。
empty?の場合
empty?の場合を見てみます。
""のレシーバの時にはtrueとなっています。
また、nilの値にempty?メソッドを使うとNoMethodErrorとなってしまいます。
blank?の場合
blank?の場合を見てみます。
nilのレシーバ、""のレシーバともにtrueを返しています。
なるほどそういうちがいがあったのか。
その他のメソッド
今回調べていくうちに分かったことがあるので補足しておきます。
present?
present?はblank?の反対の動きをするメソッドです。
blank?とは反対の値を返していることがわかります。
exists?
exists?メソッドとは、指定した条件のレコードがデータベースに存在するかどうかを真偽値で返すメソッドです。存在すればtrueを存在しなければfalseを返します。
つまりデータベースにおいて条件にマッチするレコードがあればtrueを返し、レコードがなければfalseを返します。
User.exists?(name: 'クロロ')
上の場合Usersテーブルのnameレコードにクロロという文字列があればtrueを返します。
おわりに
メソッドの中には意外とその場の空気で使っているものって結構あるなあと思いました。
書いてすんなり動くとそのままよくわからない状態でほったらかしてしまうことがよくあります。
時間は限られているのですが、立ち止まってバグのないアプリケーションの開発を進めていきたいと思います。
参考