3

在 Ruby 中,我很清楚最近注册的信号捕获器是优先的,所以:

Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}

如果我要对上述脚本发出“kill”,它会打印出“bar”并退出。

有没有办法,在 Ruby 本身中,为陷阱强制执行某种范围?

我的具体情况是这样的:

我们有一个应用程序,它在命名空间的 Signals 模块中定义了自己的捕获器(对于这个故事,我们只会说它只捕获“TERM”)。该代码在运行时需要在应用程序中使用,之后几乎就不用管了。

我们使用的第 3 方 gem(我不会命名),实际上在 initialize 方法中为“TERM”注册了自己的陷阱,因此最近初始化的对象将是处理整个“TERM”信号的对象应用程序有不良结果...

虽然 3rd 方 gem 的对象定义自己的陷阱可能是有意义的,但我不希望它们影响我的应用程序。

有没有人知道一种方法可以在不花哨的情况下给予非初始化非第 3 方陷阱优先级?

4

1 回答 1

3

您可以修补Signal别名Signal.trap,然后用无操作替换它:

module Signal
    class << self
        alias_method :real_trap, :trap
        def trap(*) end
    end
end

然后你可以real_trap在你的代码中使用,你正在使用的这个粗鲁的未命名的 gem 将被忽略。不过,您必须确保Signal在您的粗鲁宝石做任何事情之前已修补。

有了那个补丁,发送一个 SIGTERM 到这个代码:

Signal.trap("TERM") {puts "foo"; exit}
Signal.trap("TERM") {puts "bar"; exit}
Signal.real_trap("TERM") {puts "pancakes"; exit}

会给你煎饼。

我通常会尽量避免使用猴子补丁,但它对于解决错误和其他不良行为非常有用。

于 2012-10-23T23:03:06.537 回答