こんにちは!Webコーダー・プログラマーの貝原(@touhicomu)です。
今日は、Rubyのblank?、present?、nil?、empty?について解説します。
この記事では、
- blank?、present?、nil?、empty?とは
- blank?、present?を使えるようにする方法
- blank?、present?、nil?、empty?による判定
という基本的な内容から、
- 後置if、後置unlessとblank?の組み合わせ
- ArrayとHashからblank?な値を取り除く方法
などの応用的な使い方に関しても学習していきます。
このページで、Rubyのblank?、present?、nil?、empty?の使い方をよく把握して自分のスキルとしていきましょう!
blank?、present?、nil?、empty?とは
blank?、present?、nil?、empty?は、それそれ以下のような違いがあります。
メソッド | メソッドの意味 |
---|---|
nil? | 変数の値がnilまたは、値なしの場合、真となります。 |
empty? | 変数の値が""(文字列の場合)や値が空白の場合、真となります。 nil?との違いは、empty?は変数の値はあることはあるが、その値が空を示している、という点です。 |
blank? | nil?が真となる場合、または、empty?が真となる場合に、blank?は真となります。 簡単に言えば、blank?は値といえるものがない場合、真となります。 |
present? | present?は、blank?全く逆の動作をします。present?は、値といえるものがある場合、真となります。 |
次節以降で、実際にコードで判定してみましょう。
blank?、present?を使えるようにする方法
blank?、present?は、ActiveSupportというgemによって提供されるメソッドです。
以下のようにして、ActiveSupportをインストールしましょう。
$ gem install activesupport
また、ActiveSupportを使うには、
require ‘active_support/all’
する必要があります。
require 'active_support/all' val = "" if val.present? p "val is presented" else p "val is not presented" end
実行結果:
"val is not presented"
以上のような実行結果になれば、ActiveSupportがきちんとインストールされていて、present?、blank?が使えるようになっています。
blank?、present?、nil?、empty?の使い方比較
以下、nil?、empty?、blank?、present?について、それぞれどのような空の値の判定結果になるのかみていきましょう。
なお、nil?、empty?、blank?、present?の順で解説した方が理解がしやすいため、この順番で解説しています。
nil?による値の判定
nil?による値の判定は、以下のコードのようになります。
require 'active_support/all' v1 = nil v2 = true v3 = false v4 = [] v5 = [0] v6 = 100 v7 = "" v8 = "0" v9 = "100" p "---- nil? ----" p "nil.nil? = " + v1.nil?.to_s p "#{v2}.nil? = " + v2.nil?.to_s p "#{v3}.nil? = " + v3.nil?.to_s p "#{v4}.nil? = " + v4.nil?.to_s p "#{v5}.nil? = " + v5.nil?.to_s p "#{v6}.nil? = " + v6.nil?.to_s p "'#{v7}'.nil? = " + v7.nil?.to_s p "'#{v8}'.nil? = " + v8.nil?.to_s p "'#{v9}'.nil? = " + v9.nil?.to_s
実行結果:
"---- nil? ----" "nil.nil? = true" "true.nil? = false" "false.nil? = false" "[].nil? = false" "[0].nil? = false" "100.nil? = false" "''.nil? = false" "'0'.nil? = false" "'100'.nil? = false"
以上のように、nil?は、値がnilの場合はtrue、nil以外の場合はすべてfalseになっています。
nilとはRubyにおいて「オブジェクトが存在しない」という意味で、他の値はすべてオブジェクトです。
そのため、nilとnilでないもの(オブジェクトすべて)とは、厳密に区別されています。
empty?による値の判定
empty?による値の判定は、以下のコードのようになります。
require 'active_support/all' v1 = nil v2 = true v3 = false v4 = [] v5 = [0] v6 = 100 v7 = "" v8 = "0" v9 = "100" p "---- empty? ----" #p "nil.empty? = " + v1.empty?.to_s #=> undefined method `empty?' for nil:NilClass (NoMethodError) #p "#{v2}.empty? = " + v2.empty?.to_s #=> undefined method `empty?' for true:TrueClass (NoMethodError) #p "#{v3}.empty? = " + v3.empty?.to_s #=> undefined method `empty?' for false:FalseClass (NoMethodError) p "#{v4}.empty? = " + v4.empty?.to_s p "#{v5}.empty? = " + v5.empty?.to_s #p "#{v6}.empty? = " + v6.empty?.to_s #=> undefined method `empty?' for 100:Fixnum (NoMethodError) p "'#{v7}'.empty? = " + v7.empty?.to_s p "'#{v8}'.empty? = " + v8.empty?.to_s p "'#{v9}'.empty? = " + v9.empty?.to_s
実行結果:
"---- empty? ----" "[].empty? = true" "[0].empty? = false" "''.empty? = true" "'0'.empty? = false" "'100'.empty? = false"
以上のような実行結果になりました。
empty?は、nilやtrue、false、整数(Fixnum)には使用できません。
empty?は「値が空である」という意味ですので、値が空になることのない、nil、true、false、整数(Fixnum)に使用すると、エラーが発生します。
一方、配列や文字列の値が空である場合には、empty?はtrueを返しています。
例には挙げていませんが、ハッシュが空の場合もempty?はtrueを返します。
空でない場合はempty?はfalseを返しています。
blank?による値の判定
blank?による値の判定は、以下のコードのようになります。
require 'active_support/all' v1 = nil v2 = true v3 = false v4 = [] v5 = [0] v6 = 100 v7 = "" v8 = "0" v9 = "100" p "---- blank? ----" p "nil.blank? = " + v1.blank?.to_s p "#{v2}.blank? = " + v2.blank?.to_s p "#{v3}.blank? = " + v3.blank?.to_s p "#{v4}.blank? = " + v4.blank?.to_s p "#{v5}.blank? = " + v5.blank?.to_s p "#{v6}.blank? = " + v6.blank?.to_s p "'#{v7}'.blank? = " + v7.blank?.to_s p "'#{v8}'.blank? = " + v8.blank?.to_s p "'#{v9}'.blank? = " + v9.blank?.to_s
実行結果:
"---- blank? ----" "nil.blank? = true" "true.blank? = false" "false.blank? = true" "[].blank? = true" "[0].blank? = false" "100.blank? = false" "''.blank? = true" "'0'.blank? = false" "'100'.blank? = false"
以上のような実行結果になりました。
blank?は基本的には「nil? or empty?」と似たような結果となります。
true、falseは、nil?ではfalse、empty?ではエラーを返していましたが、blank?ではtrueの場合はfalse、falseの場合はtrueを返しています。
「空」という意味のblank?として意味が合っている結果となっています。
また、空の配列、空の文字列でもblank?はtrueを返しています。
これも「空」という意味として合っています。
present?による値の判定
present?による値の判定は、以下のコードのようになります。
require 'active_support/all' v1 = nil v2 = true v3 = false v4 = [] v5 = [0] v6 = 100 v7 = "" v8 = "0" v9 = "100" p "---- present? ----" p "nil.present? = " + v1.present?.to_s p "#{v2}.present? = " + v2.present?.to_s p "#{v3}.present? = " + v3.present?.to_s p "#{v4}.present? = " + v4.present?.to_s p "#{v5}.present? = " + v5.present?.to_s p "#{v6}.present? = " + v6.present?.to_s p "'#{v7}'.present? = " + v7.present?.to_s p "'#{v8}'.present? = " + v8.present?.to_s p "'#{v9}'.present? = " + v9.present?.to_s
実行結果:
"---- present? ----" "nil.present? = false" "true.present? = true" "false.present? = false" "[].present? = false" "[0].present? = true" "100.present? = true" "''.present? = false" "'0'.present? = true" "'100'.present? = true"
以上のような実行結果となりました。
基本的にpresent?は、!blank?と等価な判定を行います。
blank?ではtrueを返していた、nil、false、空の配列、空の文字列には、present?はfalseを返しています。
また、blank?でfalseを返していた値のあるオブジェクトには、present?はtrueを返しています。
後置if、後置unlessとblank?の組み合わせ
if文、後置ifとblank?
通常、blank?を使用する際は、if文の条件式にblank?を指定します。
require 'active_support/all' page = "<title>hello, world</title>" if page.blank? page = "<title>default page</title>" end puts page
実行結果:
<title>hello, world</title>
以上の例では、page変数が空の場合はデフォルト値、空でない場合はそのままの値を使用します。
次に、少し応用的な例として後置ifを使ってblank?を併用してみます。
require 'active_support/all' page = "<title>hello, world</title>" page = "<title>default page</title>" if page.blank? puts page
実行結果:
<title>hello, world</title>
この例でも、page変数が空の場合はデフォルト値、空でない場合はそのままの値を使用します。
後置ifを使うことで、幾分かコードが簡潔になりました。
このように、blank?系のメソッドは、ifやelsif、後置ifなどその時々で適切な使用のしかたをすると、コードが簡潔になり、コードが読みやすくなります。
unless文、後置unlessとblank?
unlessとblank?を組み合わせると、変数が空でない場合にunless文のコードが実行されます。
以下のサンプルコードで確認してみましょう。
以下のサンプルコードでは、<script>タグが出てきます。
<script>タグは、src属性に指定されたJavaScriptファイルを読み込むタグです。
ここでは、jsフォルダ内にあるbootstrap.jsとjquery.jsというJavaScriptファイルを読み込む<script>タグを扱っています。
require 'active_support/all' js = '<script src="js/bootstrap.js"></script>' unless js.blank? js = '<script src="js/jquery.js"></script>' + "\n" + js end puts js
実行結果:
<script src="js/jquery.js"></script> <script src="js/bootstrap.js"></script>
以上のように、変数jsが空でないために、unless文のコードが実行され、元の変数jsに新たに<script>タグが追加されています。
これを後置unlessに置き換えてみると、以下のようなサンプルコードになります。
require 'active_support/all' js = '<script src="js/bootstrap.js"></script>' js = '<script src="js/jquery.js"></script>' + "\n" + js unless js.blank? puts js
実行結果:
<script src="js/jquery.js"></script> <script src="js/bootstrap.js"></script>
後置unlessの前の文が多少長く、少し読みにくいですが、簡潔なコードになりました。
ただ、後置if、後置unlessともに、前の文が長くなると読みにくくなるため、その時々で適切なやり方を選択されてください。
あくまで、コードを簡潔にしデバッグやテストをしやすくすることが目的です。
ArrayとHashからblank?な値を取り除く方法
Arrayからblank?な値を取り除く方法
配列(Array)の中でblank?がtrueを返す空の値の要素を取り除く方法をみていきましょう。
active_supportのrejectメソッドを使用します。
require 'active_support/all' array = ['1st', nil, '', '4th', true, [], '7th'] p array.reject(&:blank?)
実行結果:
["1st", "4th", true, "7th"]
以上の例では、rejectメソッドにblank?のシンボルをProcとして渡しています。
これにより、配列(Array)からblank?がtrueを返す空の値を取り除くことができました。
blank?の他、empty?なども渡せますので、皆さんで試されてみてください。
Hashからblank?な値を取り除く方法
配列(Array)ではrejectメソッドによりうまくblank?がtrueを返す値を取り除くことができました。
ハッシュ(Hash)では、配列と違い、キーと値がありますので、どちらの値をblank?と判定するのか、rejectメソッドに指定しないといけません。
具体的には、rejectメソッドのブロックにて、ブロック引数に渡されるキーと値のどちらかにblank?を指定しブロックの返値にします。
実際のサンプルコードをみていきましょう。
require 'active_support/all' hash = { a:'1st', b:nil, c:'', d:'4th', e:true, f:[], g:'7th' } p hash.reject { |k,v| v.blank? }
実行結果:
{:a=>"1st", :d=>"4th", :e=>true, :g=>"7th"}
以上のように、ハッシュの値vに対してblank?を適用しています。
その結果、実行結果では、ハッシュの値がblank?でtrueとなるキーと値のペアは、ハッシュから取り除かれています。
このように、配列の場合と違い、キーと値がありますので、ハッシュにrejectメソッドを使用する場合は、ブロックの指定が必要になります。
まとめ
今回は、Rubyのblank?、present?、nil?、empty?について学習しました!
学習のポイントを振り返ってみましょう!
- blank?、present?、nil?、empty?により値が空かどうかの判定ができる
- blank?、present?は、active_supportのgemをインストールすることで使用できる
- 後置if、後置unlessとblank?を組み合わせて見通しの良いコードが書ける
- rejectメソッドによってArrayとHashからblank?な要素を取り除ける
以上の内容を再確認し、ぜひ自分のプログラムに生かし学習を進めてください!