Я переживаю этап, пытаясь избежать временных переменных и чрезмерного использования условных условий, где я могу использовать более жидкий стиль кодирования. Мне очень понравилось использование #tap
в тех местах, где я хочу получить значение, которое мне нужно вернуть, но сделайте что-нибудь с ним, прежде чем я его верну.
def fluid_method
something_complicated(a, b, c).tap do |obj|
obj.update(:x => y)
end
end
Vs. процедурный:
def non_fluid_method
obj = something_complicated(a, b, c)
obj.update(:x => y)
obj # <= I don't like this, if it avoidable
end
Очевидно, что приведенные выше примеры просты, но, тем не менее, это довольно распространенный стиль кодирования в рубиновом сообществе. Я иногда использую #inject
для передачи объекта через серию фильтров:
things.inject(whatever) do |obj, thing|
thing.filter(obj)
end
Vs. процедурный:
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
здесь.
Какие еще шаблоны я могу использовать здесь. Я понимаю, что это всего лишь бессмысленный сахар для некоторых людей, и что я должен просто перейти на более интересные проблемы, но я пытаюсь научиться писать в более функциональном стиле, поэтому мне просто интересно, что определили долгосрочные рубисты чтобы быть хорошим способом решения подобных ситуаций. Эти примеры очень упрощены.