備忘録的な何か

技術ブログ的な何かです

Rubyのnilの挙動を利用する

皆さんご存知の通り、RubyはnilはNilClassのオブジェクトである。

 

NilClass.instance_methods(false).sortとしてみると、結構な関数が定義されている。

 => [:&, :^, :inspect, :nil?, :rationalize, :to_a, :to_c, :to_f, :to_h, :to_i, :to_r, :to_s, :|] #ruby2.0

 

ここで、それぞれのメソッドの動作を確認してみる。(記号メソッドは除く)

 

[:inspect, :nil?, :rationalize, :to_a, :to_c, :to_f, :to_h, :to_i, :to_r, :to_s].map{|meth| nil.send(meth) }

 => ["nil", true, (0/1), [ ], (0+0i), 0.0, {}, 0, (0/1), ""] 

 

ここで、面白いと思うのは、nil.to_a #=> [ ]である。

 

例えば、配列が来るかnilが来るかわからない状況があったとする。

そういう時は、activesupportのtryやpresenceを利用する場合が多い。

arr.try(:first) #=>最初の要素をとる(nilまたは空配列の時はnilを返す)

arr.presence || [ ] #=>nilか空配列の時は[ ]とする。

 

こういう時に、to_aメソッドを利用すれば同じことができる。(多分)

arr.to_a[0] #=>最初の要素をとる(nilまたは空配列の時はnilを返す)

arr.to_a #=>nilか空配列の時は[ ]とする。

 

さらに、enumerableの関数を利用する場合は、presenceより使い勝手が良い。

arr.to_a.map{|x| hoge x } #=> (arr.presence || []).map{|x| hoge x}でも可能。

 

Ruby2.0ではto_hメソッドも追加されているので、色々と面白いことができるかもしれない。

 

ちなみに、Array#to_aとHash#to_hはselfが返ってくるようだ。(Rubyist的には常識?)

a = [1,2,3]

 b = a.to_a    # => [1, 2, 3] 

 b << 2

 a                   # => [1, 2, 3, 2] 

a.equal? b    #=> true

 

a = {x:1}

b = a.to_h   #=> {:x=>1} 

b[:y] = 2

a                  #=> {:x=>1, :y=>2} 

a.equal? b    #=> true