每当我的程序停止执行时(无论是在被cmd-c关闭时还是遇到异常时),我都想采取一些操作来正确关闭。
当我做cmd-c时,我收到信号TERM。当程序遇到引发的异常时,会发送什么信号?如何使用 Signal.trap(...) 捕获它?
代码包装在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
异常不是信号。 Ruby 解释器处理用户代码中的所有异常;没有什么可困住的。
如果要处理异常,则需要在rescue
块中执行此操作。
您无法将异常捕获为信号,但您可以在使用 'EXIT'
信号引发异常时执行某些操作:
Signal.trap('EXIT') do
puts "Terminating..."
shutdown()
end
但是,我只是说你可以这样做;你真的应该使用begin
和rescue
。
点机智的异常不是通过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!
作为上述解决方案的替代方法,您可以研究at_exit方法。