rubyでjavaのoptionalのようなことをしたい

  • このエントリーをはてなブックマークに追加

以下のようなことをもっとスマートに書きたい。

h = {}
node = doc.at_css(".title")
unless node.nil?
h[:title] = node.text
h[:href] = node.attr("href")
end

Ruby2.6にはthenというメソッドが追加されました。これと2.3で追加されたsafe operation nagigatorを利用します。

thenはselfを引数としたブロックを評価し、ブロックの結果を返します。

ret_val = obj.then{ |x| val } # obj == x
# ret_val == val

&.と組み合わせる事でjavaのoptionalみたいな事ができます。orElseみたいな事はできません。

h = {}
doc.at_css(".title")&.then{ |node|
# doc.at_css(".title")の結果がnot nilの場合、nodeに値が入ってこのブロックが実行される
h[:title] = node.text
h[:href] = node.attr("href")
}
# もしくはきちんと戻り値を使ってハッシュを作る
# ただしdoc.at_css(".title")がnilの場合、hがnilになる.
h = doc.at_css(".title")&.then{ |node|
h[:title] = node.text
[ :title, node.text, :href, node.attr("href") ]
}.to_h

DOM操作をするとき、unless nil判定が多くなるので、省略できて便利!

title = node.at_css(".title")&.text

参考