The important bit there is that all the stuff you can reasonably expect to
recover from is under StandardError. Because of this, a default rescue block
will not catch anything that isn't a StandardError. The observant reader will
notice that I helpfully showed Interrupt's position in the hierarchy. The
observant reader will also notice that it is not a subclass of StandardError.
This means that you need to catch it explicitly, or it will cause a crash.
---------------------------
But is it really true? I do:
----
begin
raise Interrupt
rescue
puts "rescued !!!"
end
----
The important bit there is that all the stuff you can reasonably expect to
recover from is under StandardError. Because of this, a default rescue
block will not catch anything that isn't a StandardError. The observant
reader will notice that I helpfully showed Interrupt's position in the
hierarchy. The observant reader will also notice that it is not a subclass
of StandardError. This means that you need to catch it explicitly, or it
will cause a crash. ---------------------------
But is it really true? I do:
----
begin
raise Interrupt
rescue
puts "rescued !!!"
end
----
Stefano Crocco wrote:
>> Exception
>> - StandardError
>> - RuntimeError
>> - ZeroDivisionError
>> - ScriptError
>> - SyntaxError
>> - SystemExit
>> - SignalException
>> - Interrupt
>>
>> begin
>> raise Interrupt
>> rescue
>> puts "rescued !!!"
>> end
>
> For me, using ruby 1.8.7, patchlevel 22 on Gentoo Linux, your code works
> as the article says, that is the exception is not being caught.
Same with p22 on Ubuntu. (I think I compiled it, too.)
> p Interrupt.ancestors
[Interrupt, SignalException, Exception, Object, Wirble::Shortcuts,
PP::ObjectMixin, Kernel]
It's different!
Also, put p $! into the rescue handler to see _what_ you rescued!
-----------
require 'timeout'
begin
raise Interrupt
rescue
puts "rescued !!!"
puts $!
end
----------
~# ./test.rb
rescued !!!
wrong number of arguments (0 for 1)
¿?
begin
raise Interrupt
rescue => e
puts "rescued !!!: #{e.class}"
end
It's ArgumentError in 1.8.6, and nothing (the rescue doesn't happen)
in 1.9.
David
···
On Mon, 21 Jul 2008, Iñaki Baz Castillo wrote:
El Domingo, 20 de Julio de 2008, Phlip escribió:
--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails July 21-24 Edison, NJ
Advancing With Rails August 18-21 Edison, NJ
See http://www.rubypal.com for details and updates!
> p Interrupt.ancestors
[Interrupt, SignalException, Exception, Object, Wirble::Shortcuts,
PP::ObjectMixin, Kernel]
It's different!
Also, put p $! into the rescue handler to see _what_ you rescued!
-----------
require 'timeout'
begin
raise Interrupt
rescue
puts "rescued !!!"
puts $!
end
----------
~# ./test.rb
rescued !!!
wrong number of arguments (0 for 1)
Right here is your problem, same thing is happening to me (ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]) For certain reasons raise throws ArgumentError (which then gets caught by single rescue) for Interrupt without additional parameters.
This will probably work if you just need to raise Interrupt:
Did you expect your program to do anything after printing "rescued !!!" ?
Assuming you are addressing a senior enjinere, not a neophyte, yes I could tell the difference between an interrupt and the rest of my program running. It has major side-effects; I stuck the sample code at the top of my current project.
Curiously, this is what the original code was doing:
begin
raise Interrupt
rescue Object
p $!.class # sez Interrupt
end
I didn't catch it either - 'raise' raises the given object, which here was class Interrupt, and the metaclass itself of course does not inherit StandardError.
Try:
begin
raise Interrupt.new('L.A. woman')
rescue
p $!.class
end
That does not invoke the rescue, and does clobber the program, all for the correct reasons. And rescue Interrupt catches it.
Did you expect your program to do anything after printing "rescued !!!" ?
Assuming you are addressing a senior enjinere, not a neophyte, yes I could tell the difference between an interrupt and the rest of my program running. It has major side-effects; I stuck the sample code at the top of my current project.
Curiously, this is what the original code was doing:
begin
raise Interrupt
rescue Object
p $!.class # sez Interrupt
I get ArgumentError with 1.8.6 and Interrupt with 1.9. I'm not sure
why Interrupt needs an argument in 1.8.6.
end
I didn't catch it either - 'raise' raises the given object, which here was class Interrupt, and the metaclass itself of course does not inherit StandardError.
raise doesn't necessarily raise the object itself. It looks for an
'exception' method on the object:
obj = Object.new
=> #<Object:0xb1bc>
def obj.exception; RuntimeError.new("Problem"); end
=> nil
raise obj
RuntimeError: Problem
Instances of Exception (and subclasses) return themselves from #exception, so in that case you would be raising the object itself.
The classes return new instances of themselves.
r = RuntimeError.exception
=> #<RuntimeError: RuntimeError>
r.object_id
=> 287910
r.exception.object_id
=> 287910
If you give #exception on an instance a new message to deliver, and
you get a new instance:
r.exception("Problem").object_id
=> 268680
David
···
On Mon, 21 Jul 2008, Phlip wrote:
--
Rails training from David A. Black and Ruby Power and Light:
Intro to Ruby on Rails July 21-24 Edison, NJ
* Advancing With Rails August 18-21 Edison, NJ
* Co-taught by D.A. Black and Erik Kastner
See http://www.rubypal.com for details and updates!
Philip you said that it was so, by confirming an output that indicated
the contrary. As a hopeless formalist I trusted the output more than
what you were writing in informal language, my error, I suppose.
BTW Philip you should never assume, you know why of course ;).
Cheers
Robert
···
On Sun, Jul 20, 2008 at 7:59 PM, Phlip <phlip2005@gmail.com> wrote:
Did you expect your program to do anything after printing "rescued !!!" ?
Assuming you are addressing a senior enjinere, not a neophyte, yes I could
tell the difference between an interrupt and the rest of my program running.
It has major side-effects; I stuck the sample code at the top of my current
project.