Technically, the first raises a RuntimeError with the message set to "foo" , and the second throws an exception with the message set to "foo" .
In practice, there is a significant difference between when you want to use the former and when you want to use the latter.
Simply put, you probably want a RuntimeError not a Exception . A rescue block with no argument will catch RuntimeErrors , but will NOT catch Exception s. Therefore, if you raise an Exception in your code, this code will not catch it:
begin rescue end
To catch an Exception , you will need to do this:
begin rescue Exception end
This means that in a sense, Exception is a βworseβ error than a RuntimeError , because you need to do more work to recover it.
So what you want depends on how your project performs its error handling. For example, in our demons, the main loop has an empty escape that will catch RuntimeErrors , report it, and then continue. But in one or two circumstances, we want the daemon to really die from the error, in which case we raise an Exception that goes right through our "normal error handling code" and exits.
And again, if you are writing library code, you probably want a RuntimeError rather than an Exception , as your library users will be surprised if it causes errors that an empty rescue block cannot catch, and it takes them a while to figure out why .
Finally, I have to say that RuntimeError is a subclass of the StandardError class, and the actual rule is that although you can raise any type of object, an empty rescue will by default only catch everything that inherits from StandardError . Everything else must be specific.