ruby catch-throw and efficiency
Asked Answered
B

2

7

catch in Ruby is meant to jump out of deeply nested code. In Java e.g. it is possible to achieve the same with Java's try-catch meant for handling exceptions, it is however considered poor solution and is also very inefficient. In Ruby for handling exceptions we have begin-raise-rescue and I assume it is also to expensive to use it for other tasks.

Is Ruby's catch-throw really a more efficient solution then begin-raise-rescue or are there any other reasons to use it to break nested blocks instead of begin-raise-rescue?

Bentinck answered 20/11, 2012 at 23:29 Comment(1)
If you post some ruby examples of the control structures you are asking about, it may be more clear what you mean.Strophic
E
9

In addition to being the "correct" way to get out of control structures, catch-throw is also significantly faster(10 times as fast in my testing). Check out this gist for my code and results.

Epigraph answered 21/11, 2012 at 0:16 Comment(3)
Thanks! The benchmark really clears the issue (in my case it is almost 15 times!). Should catch-throw be considered a structural style of programing -- a better practice then despised goto?Bentinck
It's your design requires catch-throw, there is probably a better design. That being said, there are definitely edge cases where catch throw make a lot of sense, especially in gem develop where you don't know how the end user will use it.Epigraph
Thanks for all explanations!Bentinck
E
8

Josh's answer is correct. I want to add more information about catch-throw and raise-rescue.

catch-throw is used for flow control whereas raise-rescue is used for exception/error handling. The different is: backtrace is not needed for catch-throw (flow control). Trust me, the main reason causes raise-rescue runs slow than catch-throw 10 times in Josh's gist is raise-rescue takes a lot time to create backtrace object.

If you want to raise without backtrace, use syntax:

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

Checkout my gist. raise without backtrace is much faster than raise with backtrace.

April 2016 Update:

I've updated my gist:

  • Fixed "break" test
  • Added benchmark tests results for newer ruby version 2.1.8, 2.2.4, 2.3.0
Emmeram answered 26/6, 2013 at 5:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.