2015-01-09 8 views
5
begin 
    raise 'foo' 
rescue 
    puts $!.inspect # => #<RuntimeError: foo> 
ensure 
    puts $!.inspect # => nil 
end 
puts $!.inspect # => nil 

Google herum gegoogelt, aber keine klare Antwort gefunden.

Möchten Sie nur die Lebensdauer (?) Von $! bestätigen, hält es Wert nur innerhalb eines rescue Blocks?

+0

Ich glaube schon, aber ich kann nicht scheinen, es zu bestätigen. –

+0

Ihre 'sure'-Linie und die darauf folgende Linie macht es komplexer als nötig. – sawa

+1

entfernen Sie den Rettungsblock und überprüfen Sie es mit nur einem ... – DGM

Antwort

4

$! hat den Fehler in dem Rettungsblock oder in dem Block sicherzustellen, wenn es keine Rettung Block:

begin 
    raise 'foo' 
ensure 
    puts $!.inspect # => #<RuntimeError: foo> 
end 

$! den Wert nil überall sonst hat.

+0

Thx! gut zu wissen. Wahrscheinlich wird dies als Antwort akzeptieren, warten Sie einfach auf einen weiteren Tag, um sicher zu sein. – huocp

0

Nein, die schreibgeschützte Variable $! ist überall sichtbar und verfügbar und enthält den Wert nil außer in Rettungsblöcken.

Es ist auch einzigartig für jeden Thread. Es ist die aktuelle Ausnahme (die English-Bibliothek nennt es $ERROR_INFO), und es wird auf nil einmal gerettet zurückgesetzt, es sei denn, es wird erneut ausgelöst, dann ist es wieder die aktuelle Ausnahme.

Von einer Datei, die keine anderen Zeilen enthält, können wir sehen, dass tatsächlich $! ist sichtbar.

puts defined?($!) 
puts $!.inspect 

irb(main):001:0> defined?($!) 
=> "global-variable" 
irb(main):002:0> $! 
=> nil 
irb(main):003:0> 

Und in IRB können wir sehen, dass es definiert und sichtbar ist.

Das ist wirklich nicht (oder sollte überhaupt nicht) überraschend, wie die $ bezeichnet, dass es "globale Variable" ist und als solches global sichtbar ist.

Ich konnte nicht finden, wo es nicht sichtbar ist. Sogar in BasicObject ist es sichtbar.

irb(main):001:0> class BasicObject 
irb(main):002:1> def is_it_visible 
irb(main):003:2>  defined?($!)                         
irb(main):004:2> end                            
irb(main):005:1> end                            
=> :is_it_visible 
irb(main):006:0> BasicObject.allocate.is_it_visible 
=> "global-variable" 
irb(main):007:0> 
+0

Entschuldigung, meine Formulierung scheint dich zu verwirren. Ich sollte fragen "does $! Nur Wert im Rettungsblock halten?". – huocp

+0

Nein, Ihre Frage war sehr klar. Nichts verwirrend für mich überhaupt. Es hält den Wert von Null außerhalb dieser Blöcke, wie Sie in Ihrem Code demonstrieren. – vgoff