class SignalLamp::Lamp

A Lamp keeps track of the watchers waiting for events and allows events to be signaled to those watchers. The primary methods used for this are watch_for() and signal().

Attributes

watchers[R]

Public Class Methods

new() click to toggle source

It’s not common to construct these objects directly. Instead, most code should use the SignalLamp::LampHolder mix-in.

# File lib/signal_lamp/lamp.rb, line 14
def initialize
  @watchers = { }
end

Public Instance Methods

signal(event_name, *event_details) click to toggle source

This method will invoke the block code of all previous calls to watch_for() that are still in effect and that match the passed event_name.

All other arguments passed to this method, assumed to be details related to the event, are passed through to all blocks invoked for this event.

# File lib/signal_lamp/lamp.rb, line 83
def signal(event_name, *event_details)
  watchers.each_value do |event_matcher, event_handler|
    if event_matcher === event_name
      event_handler.call(event_name, *event_details)
    end
  end
end
stop_watching(identifier) click to toggle source

Given an identifier passed to or returned from a previous call to watch_for(), this method will stop that code from being invoked for any future events.

# File lib/signal_lamp/lamp.rb, line 71
def stop_watching(identifier)
  watchers.delete(identifier)
end
watch_for(event_matcher, identifier: generate_identifier, &event_handler) click to toggle source

This is the primary interface for watching for events to occur.

The event_matcher parameter will be tested against signaled event names using the === operator. This allows you to match a String directly, use a Regexp to wildcard various event types (I recommend naming events with words separated by colons because these are easy to match), or a Proc that uses any kind of logic to select events. For example, you could match all events signaled on this object with ->(event_name) { true }.

You only need to worry about passing an identifier if you want to later stop watching for the events you will pick up with this call. Alternately you can save the generated identifier returned from this call and later feed that to stop_watching(). Any Ruby object that can be used as a Hash key is a valid identifier. By default, a UUID String will be generated.

The block passed to this call is the code that will actually be invoked when an event is signaled and the name is matched. The block will be passed the matched event name (useful with dynamic matchers that could select various events) followed by all arguments passed to signal() for the event.

# File lib/signal_lamp/lamp.rb, line 45
def watch_for(event_matcher, identifier: generate_identifier, &event_handler)
  watchers[identifier] = [event_matcher, event_handler]
  identifier
end
watch_for_one(event_matcher, &event_handler) click to toggle source

This is a shortcut used to create a watch_for() call that will only trigger for one event. After the block is called the first time, stop_watching() is automatically called.

# File lib/signal_lamp/lamp.rb, line 55
def watch_for_one(event_matcher, &event_handler)
  identifier = generate_identifier
  watch_for(event_matcher, identifier: identifier) do |*event_args|
    begin
      event_handler.call(*event_args)
    ensure
      stop_watching(identifier)
    end
  end
end

Private Instance Methods

generate_identifier() click to toggle source
# File lib/signal_lamp/lamp.rb, line 93
def generate_identifier
  SecureRandom.uuid
end