2012-11-20 16 views
5

catch w Ruby ma wyskoczyć z głęboko zagnieżdżonego kodu. W języku Java, np. Możliwe jest osiągnięcie tego samego z obsługą Javy try-catch przeznaczoną do obsługi wyjątków, jednak jest ona uważana za słabe rozwiązanie i jest również bardzo nieefektywna. W Ruby do obsługi wyjątków mamy begin-raise-rescue i zakładam, że jest również drogie, aby użyć go do innych zadań.Rzut ruby ​​i skuteczność

Czy Ruby jest catch-throw naprawdę bardziej wydajnym rozwiązaniem niż begin-raise-rescue, czy istnieją inne powody, aby użyć go do rozbicia zagnieżdżonych bloków zamiast begin-raise-rescue?

+0

Jeśli zamieścisz kilka rubinowych przykładów struktur kontrolnych, o które pytasz, może być bardziej zrozumiałe, co masz na myśli. –

Odpowiedz

5

Oprócz bycia "poprawnym" sposobem na wydostanie się ze struktur kontrolnych, catch-throw jest również znacznie szybszy (10 razy szybszy w moich testach). Sprawdź kod this gist pod kątem mojego kodu i wyników.

+0

+1 do testu porównawczego. – steenslag

+0

Dzięki! Benchmark naprawdę rozwiązuje ten problem (w moim przypadku jest to prawie 15 razy!). Czy rzut obronny powinien być uważany za strukturalny styl programowania - lepszą praktyką niż pogarszanie goto? – wrzasa

+0

Twój projekt wymaga rzutu catch, prawdopodobnie istnieje lepszy projekt. W związku z tym są zdecydowanie przypadki, w których rzut z catch'em ma wiele sensu, szczególnie w gemie, w którym nie wiesz, w jaki sposób użytkownik końcowy go użyje. – Josh

5

Josh's answer jest poprawna. Chcę dodać więcej informacji o catch-throw i raise-rescue.

catch-throw służy do kontroli przepływu, natomiast raise-rescue służy do obsługi wyjątków i błędów. Różny to: backtrace nie jest potrzebny dla catch-throw (kontrola przepływu). Zaufaj mi, główny powód, dla którego raise-rescue działa wolniej niż catch-throw 10 razy w Josh's gist jest raise-rescue trwa dużo czasu, aby utworzyć obiekt backtrace.

Jeśli chcesz raise bez backtrace, użyj składni:

raise <type>, <message>, <backtrace> 

kasę my gist. raise without backtrace jest znacznie szybszy niż raise with backtrace.

kwietnia 2016 Aktualizacja:

zaktualizowałem my gist:

  • Fixed "break" test
  • Dodane wyniki testów porównawczych dla nowszej wersji ruby ​​2.1.8, 2.2.4, 2.3.0