2014-11-18 16 views
6

To pytanie jest trochę skomplikowane do sformułowania, ale zrobię co w mojej mocy. Koryta naszego kodu mamy fragmenty, takie jakPowrót z kontekstu powyżej

response = do_something() 
return response unless response.ok? 

miałem myśleć o pisaniu metodę otoki które usuwania potrzebę tego kroku, a to wyglądać mniej więcej tak

def rr(&block) 
    response = yield 
    unless response.ok? 
    # somehow do return but in context above (magic needed here) 
    end 
    response 
end 

Potem będę mógł aby zminimalizować kod z góry za

response = rr { do_something() } 

wydaje się niemożliwe, ale jest to Ruby więc może jest jakaś droga?

+1

Oprócz implementacji 'rr', myślę, że musisz nazwać to:' response = rr {do_something} '. – zwippie

+0

Dzięki, masz rację. –

Odpowiedz

0

Nie chcesz po prostu napisać wrappera, który dokładnie to robi? Funkcjonalnie wydaje jesteś po prostu ignorowanie innych niż ok? odpowiedzi:

def rr 
    response = yield 

    response.ok? ? response : nil 
end 

Może jestem brakuje czegoś tutaj, ale ja nie rozumiem, dlaczego trzeba by wymusić return w innym kontekście, coś, co nie jest nawet możliwe i tak.

+0

Wdrożenie jest tutaj tylko przykładem, miałem nadzieję na coś, co pozwoliłoby mi propagować powrót do kontekstu powyżej. Mamy setki wymienionych fragmentów w naszym kodzie i szukałem sposobu na refaktoryzację. –

+2

Potrzebny będzie inny wzór. Jak wskazuje Ajedi32, wyjątki są jedną z form kontroli przepływu, którą możesz chcieć sprawdzić. – tadman

2

Poprawny sposób, aby powrócić na wielu warstwach stosu, gdy coś pójdzie nie tak (co wydaje się być to, co staramy się robić) jest podniesienie wyjątek:

class RequestFailedException < StandardError; end 

def rr(&block) 
    response = yield 
    unless response.ok? 
    raise RequestFailedException, "Response not okay: #{response.inspect}" 
    end 
    response 
end 

Zastosowanie:

def do_lots_of_things() 
    rr { do_something } 
    rr { do_something_else } 
    rr { another_thing } 
end 

begin 
    do_lots_of_things 
rescue RequestFailedException => e 
    # Handle or ignore error 
end