在Ruby中,我很清楚最近注册的信号捕获器是优先的,所以:
Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
如果我要对上面的脚本发出'kill',它会打印出“bar”并退出。
在Ruby本身中,是否有办法为捕获者强制实施某种范围?
我的具体情况如下:
我们有一个应用程序定义了自己的捕获器(对于这个故事,我们只是说它只捕获“TERM”)在命名空间的信号模块中。该代码在运行时需要进入应用程序,之后几乎不用了。
我们使用的第三方gem(我不会命名名称),实际上在初始化方法中为“TERM”注册了自己的捕获器,因此最近初始化的对象将是一个处理整个应用程序的“TERM”信号,结果不理想......
虽然第三方宝石的对象定义了自己的捕手可能有意义,但我不希望它们影响我的应用。
是否有人知道如何让非初始化非第三方捕手优先而不会过于花哨?
答案 0 :(得分:3)
您可以将Signal
修补程序添加到别名Signal.trap
,然后将其替换为no-op:
module Signal
class << self
alias_method :real_trap, :trap
def trap(*) end
end
end
然后你可以在代码中使用real_trap
,这个粗俗的未命名的宝石将会被忽略。你必须确保在你的粗鲁宝石做任何事情之前修补了Signal
。
使用该补丁,将SIGTERM发送到此代码:
Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
Signal.real_trap("TERM") {puts "pancakes"; exit}
会给你煎饼。
我通常会尽量避免猴子修补,但它对于克服错误和其他不良行为非常有用。