タップのような組み合わせメソッドですが、別の値を返すことはできますか?
概要
私は、より流動的なコーディング スタイルを使用できるように、一時変数と条件の過度の使用を回避しようとする段階を経ています。私は、返す必要がある値を取得したいが、値を返す前に何らかの処理を行いたい場所で #tap を使用することを非常に気に入っています。
def fluid_method
something_complicated(a, b, c).tap do |obj|
obj.update(:x => y)
end
end
対手順:
def non_fluid_method
obj = something_complicated(a, b, c)
obj.update(:x => y)
obj # <= I don't like this, if it's avoidable
end
明らかに上記の例は単純ですが、それでもこれは Ruby コミュニティでは非常に一般的なコーディング スタイルです。 #inject を使用してオブジェクトを一連のフィルターに渡すこともあります。
things.inject(whatever) do |obj, thing|
thing.filter(obj)
end
対手順:
obj = whatever
things.each do |thing|
obj = thing.filter(obj)
end
obj
現在、次のような条件が繰り返し使用されることに直面しており、それを処理するためのより流動的なアプローチを探しています。
def not_nice_method
obj = something_complex(a, b, c)
if a_predicate_check?
obj.one_more_method_call
else
obj
end
end
(少し) よりクリーンな解決策は、重複を犠牲にして一時変数を避けることです。
def not_nice_method
if a_predicate_check?
something_complex(a, b, c).one_more_method_call
else
something_complex(a, b, c)
end
end
ここでは #tap に近いものを使いたい気持ちが抑えられませんが。
他にどのようなパターンに従うことができますか。一部の人々にとって、これはすべて無意味な砂糖であることはわかっています。もっと興味深い問題に移るべきだとは思いますが、私はより機能的なスタイルで書くことを学ぼうとしているので、長年の Rubyist が何を判断したかに興味があります。このような状況に対処する良い方法になります。これらの例は大幅に簡略化されています。
解決策
オブジェクト#を次のように定義します。
class Object
def as
yield self
end
end
そして、次のように書くことができるようになりました。
def not_sure_this_is_nice_enough_method1
something_complex(a, b, c).as do |obj|
a_predicate_check? ? obj.one_more_method_call : obj
end
end