What is the difference between exit and abort?

x-yuri picture x-yuri · Apr 28, 2014 · Viewed 33.8k times · Source

The abort documentation says abort will

Terminate execution immediately, effectively by calling Kernel.exit(false).

What exactly does "immediately" mean? What is the difference between abort and exit with non-true status?

Answer

quetzalcoatl picture quetzalcoatl · Apr 28, 2014

"Exit, Exit! Abort, Raise…Get Me Outta Here!" describes everything you'd want to know I think.

In short:

  • Kernel.exit(code) "exits" the script immediately and returns the code to the OS, however, just before doing it, it calls any registered at_exit handler that your code could have registered.
  • Kernel.exit!(code) does the same, but exits immediatelly, no at_exit handlers called.
  • Kernel.abort(message) takes a message that will be printed to STDERR just before exiting with a failure code=1.

Different values of exit codes are barely suitable for detecting problems and debugging the code. However, they are very simple to use and making the parent process read them is almost trivial. Hence, exit and exit!.

If you can spend more time and make the error checking more robust, you'll need some serious error messages, not just codes. Traditionally, you can print them to STDERR if it exists. You can print manually to STDERR via normal puts, but exit-codes will still be used at the lowest level.

Printing to STDERR does not mark your job automatically as failed, so, abort was created to allow you to write and quit easily. A default exit code of 1 is enough to mark the FAIL condition, as it's assumed that all the real contextual information will be included in the error messages provided by you.

Also note that any unhanded exceptions, such as raise "wtf" with no rescue anywhere, actually behave as if calling Kernel.abort: they print to STDERR and use exitcode=1.

You said exit(false) but the exit! documentation says that the parameter is status code to be used.

I've just checked that on Windows and Ruby 1.9.3:

exit 0       # quits with code: 0
exit 1       # quits with code: 1
exit false   # quits with code: 1
exit true    # quits with code: 0

which really surprises me, as I'd assume that false would be coerced to 0 in the traditional C way. So, maybe you should rather be using integers like 0 or 1 to be perfectly clear about what code will be used.