2011-02-25 16 views
14

¿Cómo se comporta SystemExit de manera diferente a otros Exception s? Creo que entiendo algunos de los razonamientos sobre por qué no sería ser bueno para plantear una excepción adecuada. Por ejemplo, usted no quiere que algo extraño como esto suceda:¿Es SystemExit un tipo especial de excepción?

begin 
    exit 
rescue => e 
    # Silently swallow up the exception and don't exit 
end 

Pero cómo hace el rescueSystemExit ignoran? (¿Qué criterios utiliza?)

+1

Esto tiene que ser un duplicado. –

+0

@AndrewGrimm Ciertamente es una pregunta frecuente de la lista de correo y el IRC, pero no puedo encontrar esta pregunta exactamente en S/O. Lo más cerca que encontré fue _ ["¿Qué excepciones captas cuando no especificas una clase de excepción en Ruby?] (Http://stackoverflow.com/questions/2748515/which-exceptions-do-you-catch-when -you-dont-specified-a-exception-class-in-ruby) _, pero es una especie de respuesta duplicada, no duplicada. – Phrogz

+0

@Andrew Pensé que alguien más tenía que haber preguntado lo mismo también, pero no encontré nada que respondiera específicamente cómo se maneja 'SystemExit'. @Phrogz Gracias por el enlace a la Q. relacionada. –

Respuesta

20

Cuando se escribe rescue sin una o más clases, como la escritura: it is the same

begin 
    ... 
rescue StandardError => e 
    ... 
end 

hay excepciones que no se heredan de StandardError, sin embargo. SystemExit es uno de estos, por lo que no se captura. Aquí es un subconjunto de la jerarquía en Ruby 1.9.2, que se puede find out yourself:

BasicObject 
    Exception 
    NoMemoryError 
    ScriptError 
     LoadError 
     Gem::LoadError 
     NotImplementedError 
     SyntaxError 
    SecurityError 
    SignalException 
     Interrupt 
    StandardError 
     ArgumentError 
     EncodingError 
     Encoding::CompatibilityError 
     Encoding::ConverterNotFoundError 
     Encoding::InvalidByteSequenceError 
     Encoding::UndefinedConversionError 
     FiberError 
     IOError 
     EOFError 
     IndexError 
     KeyError 
     StopIteration 
     LocalJumpError 
     NameError 
     NoMethodError 
     RangeError 
     FloatDomainError 
     RegexpError 
     RuntimeError 
     SystemCallError 
     ThreadError 
     TypeError 
     ZeroDivisionError 
    SystemExit 
    SystemStackError 
    fatal 

este modo puede capturar simplementeSystemExit con:

begin 
    ... 
rescue SystemExit => e 
    ... 
end 

... o puede optar por capturar todos los excepción, incluyendo SystemExit con:

begin 
    ... 
rescue Exception => e 
    ... 
end 

Inténtelo usted mismo:

begin 
    exit 42 
    puts "No no no!" 
rescue Exception => e 
    puts "Nice try, buddy." 
end 
puts "And on we run..." 

#=> "Nice try, buddy." 
#=> "And on we run..." 

Tenga en cuenta que este ejemplo no funcionará en (algunas versiones de?) IRB, que suministra su propio método de salida que enmascara el objeto # normal de salida.

En 1.8.7:

method :exit 
#=> #<Method: Object(IRB::ExtendCommandBundle)#exit> 

En 1.9.3:

method :exit 
#=> #<Method: main.irb_exit> 
+1

Gracias por la información.Sabía que podía capturar 'SystemExit' por sí mismo, pero no sabía que al no especificar una clase de excepción solo se rescataran las excepciones' StandardError'. Parece explicarlo, ¡gracias! –

+0

Esto es increíble para probar si algo sale o no –

0

ejemplo simple:

begin 
    exit 
    puts "never get here" 
rescue SystemExit 
    puts "rescued a SystemExit exception" 
end 

puts "after begin block" 

La salida status/success?, etc se puede leer también :

begin 
    exit 1 
rescue SystemExit => e 
    puts "Success? #{e.success?}" # Success? false 
end 

begin 
    exit 
rescue SystemExit => e 
    puts "Success? #{e.success?}" # Success? true 
end 

Lista completa de métodos: [:status, :success?, :exception, :message, :backtrace, :backtrace_locations, :set_backtrace, :cause]

Cuestiones relacionadas