言語の機能をなるべく使うという条件で、シンプルに書くことを目指す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 } }