Rubyの「nil?・empty?」とRailsの「blank?・present?」について

f:id:ryoutaku_jo:20190906011333p:plain

【結論】

nil?メソッドは、レシーバーがnilのときtrueを返し、nilではない場合falseを返す

empty?メソッドは、オブジェクトが空(空文字列("")・空配列([])・空ハッシュ({})のときtrueを返し、1つ以上の要素があればfalseを返す。文字列・配列・ハッシュ以外に使うとエラーになる。

blank?メソッドは、オブジェクトがnil, '', ' ', [], {}, falseのときtrueを返し、1つ以上の要素があればfalseを返す

present?メソッドは、オブジェクトがnil, '', ' ', [], {}, false」以外のときにtrueを返し、それ以外はfalseを返す(blank?の逆)

【目次】

【本題】

オブジェクトの有無を判定するメソッド

Railsでオブジェクトの有無を判定する場合、細かい使い分けが出来るようにいくつかメソッドが用意されています。

それは、Rubyに組み込まれている「nil?・empty?」メソッドと、RailsActiveSupportによって提供されている「blank?・present?」です。

今回は、それらの仕様をまとめます。

nil?メソッド

レシーバーがnilのときtrueを返し、nilではない場合falseを返すメソッドです。

a = nil
a.nil?
# => true

a = 0
a.nil?
# => false

a = ''
a.nil?
# => false

a = []
a.nil?
# => false

RubyのObjectClassのメソッドなので、全てのオブジェクトで使用可能です。

empty?メソッド

オブジェクトが空(空文字列("")・空配列([])・空ハッシュ({})のときtrueを返し、1つ以上の要素があればfalseを返す。

なお、空白スペース(ホワイトスペース)だけの文字は、要素が入っていると見なされて、falseを返します。

a = ''
a.empty?
# => true

a = [ ]
a.empty?
# => true

a = {}
a.empty?
# => true

a = ' '
a.empty?
# => false

a = 'aaa'
a.empty?
# => false

a = [1, 2, 3]
a.empty?
# => false

a = { key: 'value' }
a.empty?
# => false

なお、nilに対してempty?メソッドを利用すると、エラーが発生します。

a = nil
a.empty?
# => NoMethodError (undefined method `empty?' for nil:NilClass)

これは、empty?メソッドがString・Array・HashClassで定義されているメソッドで、NilClassでは定義されていないためです。

なので、使用できるのは文字列と配列とハッシュのみです。

blank?メソッド

オブジェクトがnil, '', ' ', [], {}, falseのときtrueを返し、1つ以上の要素があればfalseを返すメソッドです。

ObjectClassの拡張なので、nilやfalseも含めた全てのオブジェクトに対して使用することが可能です。

なお、empty?と異なり空白スペース(ホワイトスペース)だけの文字も、trueを返します。

a = nil
a.blank?
# => true

a = false
a.blank?
# => true

a = ''
a.blank?
# => true

a = ' '
a.blank?
# => true

a = []
a.blank?
# => true

a = {}
a.blank?
# => true

a = 'aaa'
a.blank?
# => false

a = [1, 2, 3]
a.blank?
# => false

a = { key: 'value' }
a.blank?
# => false

present?メソッド

オブジェクトがnil, '', ' ', [], {}, false」以外のときtrueを返し、それ以外でfalseを返すメソッドです。

blank?メソッドと全く逆の働きをするメソッドです。

これもObjectClassの拡張なので、nilやfalseも含めた全てのオブジェクトに対して使用することが可能です。

a = nil
a.present?
# => false

a = false
a.present?
# => false

a = ''
a.present?
# => false

a = ' '
a.present?
# => false

a = []
a.present?
# => false

a = {}
a.present?
# => false

a = 'aaa'
a.present?
# => true

a = [1, 2, 3]
a.present?
# => true

a = { key: 'value' }
a.present?
# => true

なおpresenceメソッドという似た働きを持つメソッドが存在します。

これは条件に一致した場合、trueではなく、レシーバーを返します。

状況によっては、こちらの方が可読性が良くなる場合があります。

ryoutaku-jo.hatenablog.com

参考情報

nil? (Object) - Rubyリファレンス

Search results: empty - Rubyリファレンス

Object

《今日の学習進捗(3年以内に10000時間に向けて)》

以前バグの原因になったコールバックの設定漏れが、別の箇所で見つかった。
アクションを追加する際に、設定が漏れていたようだった。

根本的な原因としては、onlyexpectといった条件を、拡張を見越した上で使い分けていなかった事だと考えている。
アクションを追加した際に設定をし忘れても直ぐに気づけるという観点で、権限のチェックなどは機能制限を設けるコールバックにはexpect、set_××関連にはonlyを設定するのが最も良いと考えている。
この場合、一行が長くなる懸念もあるが、設定の抜け漏れが発生するよりは良いと考えている。

なお、ファイルアップロード関連のシステムテストを拡充しているが、多少実行に時間が掛かっているように感じる。
そもそもリクエストに寄せた方が良いと感じ始めたが、リリースまでの期限も迫っているので、一旦このまま進めて、後々修正していきたい。

学習開始からの期間 :272日
今日までの合計時間:2555h
一日あたりの平均学習時間:9.4h
今日までに到達すべき目標時間:2484h
目標との解離:71h
「10,000時間」まで、

残り・・・「7445時間!」