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