3

每当我的程序停止执行(被 cmd-c 关闭或遇到异常时),我都想采取一些措施来正确关闭。

当我执行 cmd-c 时,我收到信号 TERM。当程序遇到引发的异常时发送什么信号?如何用 Signal.trap(...) 捕获它?

4

5 回答 5

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
于 2012-05-03T17:48:50.450 回答
2

异常不是信号。Ruby 解释器处理用户代码中的所有异常;没有什么可以捕获的。

如果要处理异常,则需要在一个rescue块中进行。

于 2012-05-03T17:52:53.703 回答
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!
于 2012-05-03T17:51:41.237 回答
1

您无法将异常作为信号捕获,但您可以在使用'EXIT'信号引发异常时执行某些操作:

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

但是,我只是说您可以这样做;你真的应该使用beginand rescue

于 2012-05-03T17:59:19.507 回答
1

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

于 2012-05-04T00:41:44.117 回答