Method: Stud.trap

Defined in:
lib/stud/trap.rb

.trap(signal, &block) ⇒ Object

Bind a block to be called when a certain signal is received.

Same arguments to Signal::trap.

The behavior of this method is different than Signal::trap because multiple handlers can request notification for the same signal.

For example, this is valid:

Stud.trap("INT") { puts "Hello" }
Stud.trap("INT") { puts "World" }

When SIGINT is received, both callbacks will be invoked, in order.

This helps avoid the situation where a library traps a signal outside of your control.

If something has already used Signal::trap, that callback will be saved and scheduled the same way as any other Stud::trap.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/stud/trap.rb', line 21

def self.trap(signal, &block)
  @traps ||= Hash.new { |h,k| h[k] = [] }

  if !@traps.include?(signal)
    # First trap call for this signal, tell ruby to invoke us.
    previous_trap = Signal::trap(signal) { simulate_signal(signal) }
    # If there was a previous trap (via Kernel#trap) set, make sure we remember it.
    if previous_trap.is_a?(Proc)
      # MRI's default traps are "DEFAULT" string
      # JRuby's default traps are Procs with a source_location of "(internal")
      if RUBY_ENGINE != "jruby" || previous_trap.source_location.first != "(internal)"
        @traps[signal] << previous_trap
      end
    end
  end

  @traps[signal] << block

  return block.object_id
end