プログラムが実行を停止したとき (cmd-c によってシャットダウンされたとき、または例外が発生したとき) はいつでも、適切にシャットダウンするためにいくつかのアクションを実行したいと考えています。
cmd-c を実行すると、シグナル TERM を受け取ります。プログラムが発生した例外に遭遇したときに送信されるシグナルは何ですか? これを Signal.trap(...) でトラップするにはどうすればよいですか?
プログラムが実行を停止したとき (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
ます。
上記の解決策の代わりに、at_exitメソッドを調べることができます。
例外のポイントは、信号をトラップするのではなく、ブロック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!