3

Ruby では、最後に登録されたシグナル トラッパーが優先されることをよく知っているので、次のようにします。

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

上記のスクリプトに「kill」を発行すると、「bar」が出力されて終了します。

Ruby自体に、トラッパーにある種のスコープを強制する方法はありますか?

私の特定の状況はこれです:

名前空間付きの Signals モジュールで独自のトラッパーを定義するアプリケーションがあります (この記事では、「TERM」のみをトラップするとします)。そのコードは実行時にアプリに必要であり、その後はほとんど放置されます。

私たちが使用するサードパーティの gem (名前は付けません) は、実際には初期化メソッドで"TERM" の独自のトラッパーを登録するため、最後に初期化されたオブジェクトが、全体の "TERM" シグナルを処理するオブジェクトになります。望ましくない結果を伴うアプリケーション...

サード パーティの gem のオブジェクトに独自のトラッパーを定義することは理にかなっているかもしれませんが、アプリに影響を与えたくありません。

派手になりすぎずに、非初期化、非サードパーティのトラッパーを優先する方法を知っている人はいますか?

4

1 に答える 1

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}

あなたにパンケーキを与えるでしょう。

私は通常、モンキーパッチを避けようとしますが、バグやその他の悪い動作を回避するのに非常に役立ちます。

于 2012-10-23T23:03:06.537 に答える