2012-05-03 42 views
3

任何時候我的程序停止執行(無論是通過cmd-c關閉還是遇到異常時),我都想採取一些操作來正確關閉。當發生異常並且程序停止執行時,哪個系統信號被髮送到ruby程序?

當我做cmd-c時,我收到信號TERM。當程序遇到引發的異常時發送什麼信號?如何使用Signal.trap(...)來捕獲此信息?

+0

我還應該澄清一點,我在事件機器循環中運行此代碼。在這種情況下,我應該在哪裏包裹我的保證? – user531065

回答

2

您可以將代碼包裝在begin-ensure-end區塊中。它會捕獲異常和CTRL-C。 (您可以在ensure之前添加救援條款)。

begin 
    sleep 10 #try CTRL-C here 
    raise "kaboom" #RuntimeError 
ensure 
    puts "This must be printed no matter what." 
end 
1

點機智例外不是通過Signal.trap捕獲信號,而是纏繞了可以在begin-rescue-end塊產生一個異常的代碼。您有更多的選擇,但:

begin 
    # here goes the code that may raise an exception 
rescue ThisError 
    # this code is executed when 'ThisError' was raised 
rescue ThatError, AnotherError 
    # this code is executed when 'ThatError' or 'AnotherError' was raised 
rescue 
    # this code is executed when any other StandardError was raised 
else 
    # this code is executed when NO exception was raised 
ensure 
    # this code is always executed 
end 

下面是如何使用這個更實際一些位例子:

def compute_something(x,y) 
    raise ArgumentError, 'x must not be lower than 0' if x < 0 
    x/y + y 
end 

begin 
    compute_something(-10,5) 
rescue ArgumentError 
    puts "some argument is erroneous!" 
end 

puts "---" 

x=100 
y=0 

begin 
    compute_something(x,y) 
rescue ZeroDivisionError 
    puts "division by zero! trying to fix that..." 
    y=1 
    retry 
else 
    puts "everything fine!" 
end 

puts "---" 

begin 
    compute_something(1) 
rescue => e 
    puts "the following error occured:" 
    puts e 
end 

puts "---" 

begin 
    exit 
ensure 
    puts "i am always called!" 
end 

此輸出:

some argument is erroneous! 
--- 
division by zero! trying to fix that... 
everything fine! 
--- 
the following error occured: 
wrong number of arguments (1 for 2) 
--- 
i am always called! 
+0

'救援'並不能拯救所有 - 只有標準錯誤的子類。 「救援例外」拯救了一切 –

+0

@FrederickCheung你是對的,解決了這個問題。 –

2

一個例外是不是一個信號。 Ruby解釋器處理用戶代碼中的所有異常;沒有什麼可以陷阱的。

如果要處理異常,則需要在rescue塊中執行此操作。

1

不能捕獲該異常的信號,但是當它提出使用'EXIT'信號,你可以做一些事情:

Signal.trap('EXIT') do 
    puts "Terminating..." 
    shutdown() 
end 

不過,我只是說,你可以本;你真的應該使用beginrescue

1

作爲上述解決方案的替代方案,您可以查看at_exit方法。

相關問題