Signal Lamp
A simple tool for decoupling Ruby object systems.
Synopsis
require "signal_lamp" # Step 0: load Signal Lamp
class Datum
include SignalLamp::LampHolder # Step 1: include the event methods
def initialize(value)
@value = value
end
attr_reader :value
def value=(new_value)
old_value = @value
@value = new_value
# Step 2: signal events when interesting things happen
lamp.signal("changed:value", self, old_value: old_value, new_value: new_value)
end
end
class TotalWatcher
def initialize
@total = 0
end
attr_reader :total
def watch(datum)
record_value(datum.value)
# Step 3: watch for those events
datum.lamp.watch_for("changed:value") do |_, _, details|
record_value_change(details)
end
end
private
def record_value(value)
@total += value
end
def record_value_change(old_value: , new_value: )
record_value(new_value - old_value)
end
end
ones = Datum.new(1)
tens = Datum.new(30)
#
# variation on the theme:
#
# 1. You don't have to use objects
# 2. You can watch for multiple event types at once
# 3. All signal arguments are passed through to the watcher
#
changed_event_regex = /\Achanged:/
[ones, tens].each do |datum|
datum.lamp.watch_for(changed_event_regex) do |event, changed_datum, details|
printf "%s's `%s' changed from %i to %i\n",
changed_datum.object_id,
event.sub(changed_event_regex, ""),
details.fetch(:old_value),
details.fetch(:new_value)
end
end
# this hooks event signalers to watchers
watcher = TotalWatcher.new
watcher.watch(ones)
watcher.watch(tens)
# this signals events
ones.value += 1
tens.value += 10
# this shows that the objects communicated
watcher.total # => 42
# >> 70302533065580's `value' changed from 1 to 2
# >> 70302533065560's `value' changed from 30 to 40
Description
This library is pretty much a port of the Events module in Backbone.js, with minor changes:
- The interface was made a little more Rubyish with the use of blocks,
===
, etc. - All event methods were moved behind a prefix to minimize the impact on an object's API
- Simple identifiers are used to classify, and optionally remove, watcher to signaler relationships
In other words, this is a system for decoupling objects. Some objects become "signalers" that tell anyone who is interested when "events" happen. Other objects act as "watchers" waiting for and acting on those events.
This library has nothing to do with multiprocessing. This is just a tool for managing object communication.
Installation
Install the gem:
gem install signal_lamp
or add it to your Gemfile
:
gem "signal_lamp"
Documentation
Full public API documentation is available online.
Contributing
If you have grand ideas about cool new features that could be added to Signal Lamp, I'm probably not interested. Sorry. I very much want this library to stay a simple tool that is easy to fully understand.
Of course, I'm very interested in fixing any bugs or other problems with this code. Please do send those along.
If you're unsure, feel free to create an issue. I'm happy to discuss it with you. Just don't get too mad if I pass. You are always welcome to release extensions to Signal Lamp as add-on gems.
Author
Signal Lamp was coded up by James Edward Gray II (JEG2).