Search code examples
ruby

how do you unset Signal.trap?


I have a loop that I want to stop on interrupt, but once I do this, the original behavior is lost.. How can I temporarily change the behavior of interrupt but then set it back so it can do what it normally does?

stop = false
trap = Signal.trap('INT') { stop = true } # returns "DEFAULT"
loop do
  break if stop
end
Signal.trap('INT') { trap } # <-- does not work

I know I can do:

Signal.trap('INT') do
  stop = true
  exit
end

But I would rather just let it do it's default behavior... How can I do that?


Solution

  • You almost had it, but instead of wrapping the previous handler/value in a block, you have to pass it as a positional argument:

    stop = false
    trap = Signal.trap('INT') { stop = true }
    loop do
      break if stop
    end
    Signal.trap('INT', trap) # <- this way
    

    This also works if the previous handler is a proc, i.e. procs can be given as both, block arguments (via &) or positional arguments:

    handler = proc { stop = true }
    
    Signal.trap('INT', handler)
    # is treated as:
    Signal.trap('INT', &handler)
    # which is equivalent to:
    Signal.trap('INT') { stop = true }