1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsの存在確認メソッド 使い分けメモ (any?/empty?/present?(!blank?)/nil?)

Last updated at Posted at 2020-07-01

はじめに

Railsのビューで、「画像があったら表示させる」みたいな処理を書く場面がありました。
存在確認のためのメソッドは、Rubyのもの、Railsのもの含め、いくつかあります。
ちょっと調べて、「よし、これで行こう!」とメソッドを選択してレビューに出したところ、おもいっきり玉砕したので、今後間違えないように備忘録として残しておきます。

環境

macOS Catalina Version 10.15.5
Ruby: 2.6.5
Ruby on Rails: 6.0.3

調査対象

  • any?(Ruby)
  • empty?(Ruby)
  • nil?(Ruby)
  • present?(Rails)

#動機
過去にも類似の記事はあり、実際に大部分、「rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった」に乗っからせていただきました。そのうえで、今回投稿に至った理由は、以下となります。

  • 上記投稿においてany?メソッドが触れられていなかったが、any?の挙動についても確認したかった(今回直面したのが、配列絡みの問題だったため)
  • 上記投稿のまとめの表では、
     -「ある かどうかを聞くメソッド(present?等。何かあればtrueを返す)」
     -「無い かどうかを聞くメソッド(empty?等。何も無ければtrueを返す)」
    が並べて表記されていたが、「何かある場合に〇〇を返す」というように、条件の方向を揃えた表(present?と not empty?が比較できるような表)が欲しかった
    ※もちろん上記の表のメリットとして、present?とblank?が裏の関係になっていることがわかりやすい、等があります

なお、blank?は除外しています(present?の定義が!blank?のため)。

調査方法

rails consoleを使います。

test = XXX ←ここに色々代入していく

test.any?
!test.empty?
test.present?
!test.nil?

調査結果

| | any? | !empty?
(empty?の否定)| present?
(!blank?)|!nil?
(nil?の否定)|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| Ruby/Rails | Ruby | Ruby | Rails | Ruby |
|1
数字|NoMethodError| NoMethodError|true|true|
|"foo"
文字列|NoMethodError|true|true|true|
|{key: value}
ハッシュ|true|true|true|true|
|["foo"]
配列|true|true|true|true|
|true|NoMethodError|NoMethodError|true|true|
|false|NoMethodError|NoMethodError|false|true|
|nil|NoMethodError|NoMethodError|false|false|
|""
空|NoMethodError|false|false|true|
|" "
半角スペース|NoMethodError|TRUE|FALSE|true|
|{}
空ハッシュ|false|false|false|true|
|[]
空配列|false|false|false|true|
|[nil]
配列(要素がnil)|FALSE|TRUE|TRUE|TRUE|
any?はEnumerableモジュールで定義されているため、配列やハッシュ以外で使おうとしてもNoMethodErrorとなります

要点

この結果から今後気を付けなきゃなと思ったところは、表内で大文字で強調していますが、改めて以下に記載しておきます。

  1. 半角スペースは、!empty?では存在するもの空ではないとみなされtrueを返し、present?では空とみなされfalseを返す

    ↑(修正)@scivola 様よりコメントをいただき、修正および追記しました。ありがとうございました。

     (追記)present?(もといblank?)は、空判定の出る範囲が広めであることに注意

         例:false、nil、半角スペース以外に、全角スペース、タブ(\t)、改行(\n)、Unicode(\unnnn)等も空と判定される
  2. 配列にany?を適用すると、**真の要素(=nilでない要素)**がある場合にtrueを返す。それ以外のメソッドは、真か否かに関係なく、要素があればtrueを返す。
  3. 素の nil!nil?って聞いてもfalseを返すが、 [nil]でできた配列に!nil?と聞くとtrueを返す

その他

Railsで、exists?というメソッドもあります。これは、データベースに特定の条件のデータが存在するか確かめるときに使うようで、ActiveRecord::Baseで定義されているメソッドとのことでした。そのことをつゆ知らず、当初調査対象に含めていましたが、すべてNoMethodErrorを返されました。

学び

Qiita初投稿となりました。シンプルでごく当たり前の内容だとは思いますが、アウトプットのために調べる、整理する、といった過程を通じて理解を深める良い機会となりました。
定期的に、今後の自分(≒他人)にとって役に立つ記事を投稿していきたいと思います。

参考URL

rubyの真偽判定メソッド(nil?/empty?/blank?/present?)を検証してみた結果、興味深いことがわかった

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?