Я прохожу фазу попыток избежать временных переменных и чрезмерного использования условных выражений, где я могу использовать более гибкий стиль кодирования. Мне очень понравилось использовать #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's avoidable
end
Очевидно, что приведенные выше примеры просты, но, тем не менее, это довольно распространенный стиль кодирования в сообществе ruby. Иногда я буду использовать #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
здесь.
Каким другим шаблонам я мог бы следовать здесь. Я понимаю, что это просто бессмысленный сахар для некоторых людей, и я должен просто перейти к более интересным проблемам, но я пытаюсь научиться писать в более функциональном стиле, поэтому мне просто любопытно, что определили долгосрочные рубинисты быть хорошим способом решения подобных ситуаций. Эти примеры очень упрощены.