Przechodzę przez fazę prób unikania zmiennych tymczasowych i nadużywania warunkowego, w którym mogę użyć bardziej płynnego stylu kodowania. Bardzo podobało mi się używanie #tap
w miejscach, w których chcę uzyskać wartość, którą muszę zwrócić, ale zrób coś, zanim zwrócę ją.Kombinatorowa metoda, taka jak dotknij, ale może zwrócić inną wartość?
def fluid_method
something_complicated(a, b, c).tap do |obj|
obj.update(:x => y)
end
end
Vs. proceduralnych:
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
Oczywiście powyższe przykłady są proste, ale jest to dość powszechne kodowania styl we wspólnocie rubinowym jednak. Ja czasami użyć #inject
aby przekazać obiekt przez serię filtrów TOO:
things.inject(whatever) do |obj, thing|
thing.filter(obj)
end
Vs. proceduralnych:
obj = whatever
things.each do |thing|
obj = thing.filter(obj)
end
obj
Teraz jestem w obliczu powtarzanego stosowania warunku jak na poniższej ilustracji, a patrząc na podejście bardziej płynu do przenoszenia go:
def not_nice_method
obj = something_complex(a, b, c)
if a_predicate_check?
obj.one_more_method_call
else
obj
end
end
Rozwiązanie (nieznacznie) Cleaner jest do uniknąć tymczasową zmienną kosztem powielania:
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
nie mogę pomóc, ale czuje chęć korzystania coś prawie jak#tap
tutaj.
Jakie inne wzory mogę tutaj śledzić. Zdaję sobie sprawę, że jest to po prostu bezsensowny cukier dla niektórych osób i że powinienem po prostu przejść do bardziej interesujących problemów, ale próbuję nauczyć się pisać w bardziej funkcjonalnym stylu, więc jestem ciekawy, co ustalili długoterminowi rubiści być dobrym sposobem radzenia sobie z takimi sytuacjami. Te przykłady są bardzo uproszczone.
Na ryzyko bycia pedantycznym wydaje się, że używanie kranu do wywoływania efektów ubocznych jest anty-funkcjonalne.Funkcjonalni programiści i języki unikają lub zapobiegają skutkom ubocznym. Punktem dotknięcia jest to, że nie zwróci to, co zostanie w nim wykonane. W związku z tym można go zastosować na dwa sposoby: debugowanie i metody wywołujące efekty uboczne. Funkcjonalny sposób polega po prostu na łączeniu metod lub łączeniu ich. –
Bez ryzyka, chciałbym mówić o teorii, choć obawiam się, że ten wątek zostanie zamknięty, jeśli nie będzie bezpośredniego pytania, ponieważ '# update' zwróci wartość logiczną, a nie wartość' obj' (która jest poza moja kontrola), nie dotyka rozwiązania, aby trzecie wyrażenie nie zwróciło pierwotnej wartości? Chciałbym zrozumieć bardziej poprawne techniki funkcjonalne :) – d11wtq
Ach, widzę, jak mogłem to zmienić: 'update (coś_complex (a, b, c))', gdzie zdefiniowałem 'update', aby zrobić' argument.update (: x => y) '... chociaż staje się to bardziej szczegółowe, ponieważ parametry aktualizacji muszą zostać przekazane. – d11wtq