言語の機能をなるべく使うという条件で、シンプルに書くことを目指す1。
- 人に読みやすいかということはこだわらない
- 文字数にこだわるわけでもない
課題
-
fetch_aでオブジェクトが取れればそれのx,yで作れるHashを、 - 取れなければ
fetch_bを試して取れればそれのx,yで作れるHashを、 - どちらもダメなら
nilを返す
(空想ではなく、実際に見たコードを一部省略したものです)
if a = fetch_a
{ x: a.x, y: a.y }
elsif b = fetch_b
{ x: b.x, y: b.y }
else
nil
end
if の中で代入するのは rubocop style 的に NG だそうなので、なんとかできないかなと思った。
この課題については、やりたいこと自体がかなり複雑すぎるなので、書き方を改善すればいいという問題ではない気がしたが、気にしない 2。
思いついた案
instance_eval使う
(fetch_a || fetch_b)&.instance_eval { { x: x, y: y } }
instance_eval は長いのが嫌いなので tap にしてみる。
instance_evalの代わりにtap
(fetch_a || fetch_b)&.tap { |v| break { x: v.x, y: v.y } }
v の名前づけに悩む(3回書くので、丁寧にすれば長くなるし)が、変わらない文字数でできそう
Ruby 2.7 なら Numbered parameters を使うこともできそう
tap+NumberedParameters
(fetch_a || fetch_b)&.tap { break { x: @1.x, y: @1.y } }