signal_lamp 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +126 -0
- data/Rakefile +15 -0
- data/lib/signal_lamp.rb +11 -0
- data/lib/signal_lamp/lamp.rb +97 -0
- data/lib/signal_lamp/lamp_holder.rb +18 -0
- data/lib/signal_lamp/version.rb +3 -0
- data/signal_lamp.gemspec +28 -0
- data/spec/lamp_holder_spec.rb +18 -0
- data/spec/lamp_spec.rb +86 -0
- data/spec/spec_helper.rb +17 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cb205a2b3a0cab05eae3328eaf5affb360d36d87
|
4
|
+
data.tar.gz: a2db4a1d041c62e527d924b96c5714a1ea08942c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e127a9527fc7216aea6142e4f3d5247e1f03862e6a80c9a7eee6333ed3b2e1f595721ed9fb50dc067559527dc03d9ff97505f90df36f15b74d941722f42a62c8
|
7
|
+
data.tar.gz: 2aba2811fb0e485e0aacb5095589860ce6328c9731b142444b3fc8e2c084061f4817322c9c86576378c2476fab0a82c95973a66e1937f4c044230776a3fa32dd
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 James Edward Gray II
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# Signal Lamp
|
2
|
+
|
3
|
+
A simple tool for decoupling Ruby object systems.
|
4
|
+
|
5
|
+
## Synopsis
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
require "signal_lamp" # Step 0: load Signal Lamp
|
9
|
+
|
10
|
+
class Datum
|
11
|
+
include SignalLamp::LampHolder # Step 1: include the event methods
|
12
|
+
|
13
|
+
def initialize(value)
|
14
|
+
@value = value
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :value
|
18
|
+
|
19
|
+
def value=(new_value)
|
20
|
+
old_value = @value
|
21
|
+
@value = new_value
|
22
|
+
|
23
|
+
# Step 2: signal events when interesting things happen
|
24
|
+
lamp.signal("changed:value", self, old: old_value, new: new_value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class TotalWatcher
|
29
|
+
def initialize
|
30
|
+
@total = 0
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :total
|
34
|
+
|
35
|
+
def watch(datum)
|
36
|
+
record_value(datum.value)
|
37
|
+
# Step 3: watch for those events
|
38
|
+
datum.lamp.watch_for("changed:value") do |_, _, details|
|
39
|
+
record_value_change(details)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def record_value(value)
|
46
|
+
@total += value
|
47
|
+
end
|
48
|
+
|
49
|
+
def record_value_change(old: , new: )
|
50
|
+
record_value(new - old)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
ones = Datum.new(1)
|
55
|
+
tens = Datum.new(30)
|
56
|
+
|
57
|
+
#
|
58
|
+
# variation on the theme:
|
59
|
+
#
|
60
|
+
# 1. You don't have to use objects
|
61
|
+
# 2. You can watch for multiple event types at once
|
62
|
+
# 3. All signal arguments are passed through to the watcher
|
63
|
+
#
|
64
|
+
changed_event_regex = /\Achanged:/
|
65
|
+
[ones, tens].each do |datum|
|
66
|
+
datum.lamp.watch_for(changed_event_regex) do |event, changed_datum, details|
|
67
|
+
printf "%s's `%s' changed from %i to %i\n",
|
68
|
+
changed_datum.object_id,
|
69
|
+
event.sub(changed_event_regex, ""),
|
70
|
+
details.fetch(:old),
|
71
|
+
details.fetch(:new)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# this hooks event signalers to watchers
|
76
|
+
watcher = TotalWatcher.new
|
77
|
+
watcher.watch(ones)
|
78
|
+
watcher.watch(tens)
|
79
|
+
|
80
|
+
# this signals events
|
81
|
+
ones.value += 1
|
82
|
+
tens.value += 10
|
83
|
+
|
84
|
+
# this shows that the objects communicated
|
85
|
+
watcher.total # => 42
|
86
|
+
# >> 70302533065580's `value' changed from 1 to 2
|
87
|
+
# >> 70302533065560's `value' changed from 30 to 40
|
88
|
+
```
|
89
|
+
|
90
|
+
## Description
|
91
|
+
|
92
|
+
This library is pretty much a port of [the Events module in Backbone.js](http://backbonejs.org/#Events), with minor changes:
|
93
|
+
|
94
|
+
* The interface was made a little more Rubyish with the use of blocks, `===`, etc.
|
95
|
+
* All event methods were moved behind an prefix to minimize the impact on an object's API
|
96
|
+
* Simple identifiers are used to classify, and optionally remove, watcher to signaler relationships
|
97
|
+
|
98
|
+
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.
|
99
|
+
|
100
|
+
This library has nothing to do with multiprocessing. This is just a tool for managing object communication.
|
101
|
+
|
102
|
+
## Installation
|
103
|
+
|
104
|
+
Install the gem:
|
105
|
+
|
106
|
+
```
|
107
|
+
gem install signal_lamp
|
108
|
+
```
|
109
|
+
|
110
|
+
or add it to your `Gemfile`:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
gem "signal_lamp"
|
114
|
+
```
|
115
|
+
|
116
|
+
## Contributing
|
117
|
+
|
118
|
+
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.
|
119
|
+
|
120
|
+
Of course, I'm very interested in fixing any bugs or other problems with this code. [Please do send those along.](https://github.com/JEG2/signal_lamp/issues)
|
121
|
+
|
122
|
+
If you're unsure, [feel free to create an issue](https://github.com/JEG2/signal_lamp/issues). 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.
|
123
|
+
|
124
|
+
## Author
|
125
|
+
|
126
|
+
Signal Lamp was coded up by James Edward Gray II (JEG2).
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rdoc/task"
|
3
|
+
require "rspec/core/rake_task"
|
4
|
+
|
5
|
+
RDoc::Task.new do |rdoc|
|
6
|
+
rdoc.rdoc_dir = "doc"
|
7
|
+
rdoc.main = "README.md"
|
8
|
+
rdoc.rdoc_files.include(
|
9
|
+
"README.md",
|
10
|
+
`git ls-files -z`.split("\x0").grep(%r{\Alib/})
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec::Core::RakeTask.new(:spec)
|
15
|
+
task default: :spec
|
data/lib/signal_lamp.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative "signal_lamp/version"
|
2
|
+
require_relative "signal_lamp/lamp_holder"
|
3
|
+
|
4
|
+
#
|
5
|
+
# A simple tool for decoupling Ruby object systems.
|
6
|
+
#
|
7
|
+
# See SignalLamp::Lamp and SignalLamp::LampHolder for documentation.
|
8
|
+
#
|
9
|
+
module SignalLamp
|
10
|
+
# namespace filled in by the files above
|
11
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
|
3
|
+
module SignalLamp
|
4
|
+
#
|
5
|
+
# A Lamp keeps track of the watchers waiting for events and allows events to
|
6
|
+
# be signaled to those watchers. The primary methods used for this are
|
7
|
+
# #watch_for() and #signal().
|
8
|
+
#
|
9
|
+
class Lamp
|
10
|
+
#
|
11
|
+
# It's not common to construct these objects directly. Instead, most code
|
12
|
+
# should use the SignalLamp::LampHolder mix-in.
|
13
|
+
#
|
14
|
+
def initialize
|
15
|
+
@watchers = { }
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :watchers
|
19
|
+
private :watchers
|
20
|
+
|
21
|
+
#
|
22
|
+
# This is the primary interface for watching for events to occur.
|
23
|
+
#
|
24
|
+
# The +event_matcher+ parameter will be tested against signaled event names
|
25
|
+
# using the <tt>===</tt> operator. This allows you to match a +String+
|
26
|
+
# directly, use a +Regexp+ to wildcard various event types (I recommend
|
27
|
+
# naming events with words separated by colons because these are easy to
|
28
|
+
# match), or a +Proc+ that uses any kind of logic to select events. For
|
29
|
+
# example, you could match all events signaled on this object with
|
30
|
+
# <tt>->(event_name) { true }</tt>.
|
31
|
+
#
|
32
|
+
# You only need to worry about passing an +identifier+ if you want to later
|
33
|
+
# stop watching for the events you will pick up with this call. Alternately
|
34
|
+
# you can save the generated +identifier+ returned from this call and later
|
35
|
+
# feed that to #stop_watching(). Any Ruby object that can be used as a
|
36
|
+
# +Hash+ key is a valid +identifier+. By default, a UUID +String+ will be
|
37
|
+
# generated.
|
38
|
+
#
|
39
|
+
# The block passed to this call is the code that will actually be invoked
|
40
|
+
# when an event is signaled and the name is matched. The block will be
|
41
|
+
# passed the matched event name (useful with dynamic matchers that could
|
42
|
+
# select various events) followed by all arguments passed to #signal() for
|
43
|
+
# the event.
|
44
|
+
#
|
45
|
+
def watch_for(event_matcher, identifier: generate_identifier, &event_handler)
|
46
|
+
watchers[identifier] = [event_matcher, event_handler]
|
47
|
+
identifier
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# This is a shortcut used to create a #watch_for() call that will only
|
52
|
+
# trigger for one event. After the block is called the first time,
|
53
|
+
# #stop_watching() is automatically called.
|
54
|
+
#
|
55
|
+
def watch_for_one(event_matcher, &event_handler)
|
56
|
+
identifier = generate_identifier
|
57
|
+
watch_for(event_matcher, identifier: identifier) do |*event_args|
|
58
|
+
begin
|
59
|
+
event_handler.call(*event_args)
|
60
|
+
ensure
|
61
|
+
stop_watching(identifier)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Given an +identifier+ passed to or returned from a previous call to
|
68
|
+
# #watch_for(), this method will stop that code from being invoked for any
|
69
|
+
# future events.
|
70
|
+
#
|
71
|
+
def stop_watching(identifier)
|
72
|
+
watchers.delete(identifier)
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# This method will invoke the block code of all previous calls to
|
77
|
+
# #watch_for() that are still in effect and that match the passed
|
78
|
+
# +event_name+.
|
79
|
+
#
|
80
|
+
# All other arguments passed to this method, assumed to be details related
|
81
|
+
# to the event, are passed through to all blocks invoked for this event.
|
82
|
+
#
|
83
|
+
def signal(event_name, *event_details)
|
84
|
+
watchers.each_value do |event_matcher, event_handler|
|
85
|
+
if event_matcher === event_name
|
86
|
+
event_handler.call(event_name, *event_details)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def generate_identifier
|
94
|
+
SecureRandom.uuid
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "lamp"
|
2
|
+
|
3
|
+
module SignalLamp
|
4
|
+
#
|
5
|
+
# The primary interface of SignalLamp. Mix this into an object, then use
|
6
|
+
# the #lamp() method to reach any features provided by SignalLamp::Lamp.
|
7
|
+
#
|
8
|
+
module LampHolder
|
9
|
+
#
|
10
|
+
# Returns a memoized SignalLamp::Lamp instance that can be used to
|
11
|
+
# SignalLamp::Lamp#signal() events and SignalLamp::Lamp#watch_for() events
|
12
|
+
# related to the object this module is mixed into.
|
13
|
+
#
|
14
|
+
def lamp
|
15
|
+
@lamp ||= SignalLamp::Lamp.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/signal_lamp.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative "lib/signal_lamp/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = File.basename(__FILE__, ".gemspec")
|
5
|
+
spec.version = SignalLamp::VERSION
|
6
|
+
spec.authors = ["James Edward Gray II (JEG2)"]
|
7
|
+
spec.email = %w[james@graysoftinc.com]
|
8
|
+
spec.summary = "A simple tool for decoupling Ruby object systems."
|
9
|
+
spec.description = <<END_DESCRIPTION
|
10
|
+
This is a system for decoupling objects. Some objects become "signalers" that
|
11
|
+
tell anyone who is interested when "events" happen. Other objects act as
|
12
|
+
"watchers" waiting for and acting on those events.
|
13
|
+
END_DESCRIPTION
|
14
|
+
spec.homepage = "https://github.com/JEG2/signal_lamp"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.test_files = spec.files.grep(%r{\Aspec/})
|
19
|
+
spec.extra_rdoc_files = %w[README.md]
|
20
|
+
spec.rdoc_options << "--main" << "README.md"
|
21
|
+
spec.require_paths = %w[lib]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.3"
|
25
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "ZenTest", "~> 4.10"
|
27
|
+
spec.add_development_dependency "rdoc", "~> 4.1"
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
require_relative "../lib/signal_lamp/lamp_holder"
|
4
|
+
|
5
|
+
describe SignalLamp::LampHolder do
|
6
|
+
let(:object) { Object.new }
|
7
|
+
|
8
|
+
it "adds the lamp interface to any object" do
|
9
|
+
expect(object.respond_to?(:lamp)).not_to be_true
|
10
|
+
object.extend(SignalLamp::LampHolder)
|
11
|
+
expect(object.respond_to?(:lamp)).to be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "always returns the same lamp attached to an object" do
|
15
|
+
object.extend(SignalLamp::LampHolder)
|
16
|
+
expect(object.lamp).to be(object.lamp)
|
17
|
+
end
|
18
|
+
end
|
data/spec/lamp_spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative "spec_helper"
|
2
|
+
|
3
|
+
require_relative "../lib/signal_lamp/lamp"
|
4
|
+
|
5
|
+
describe SignalLamp::Lamp do
|
6
|
+
let(:events_seen) { [ ] }
|
7
|
+
|
8
|
+
it "allows you to watch for signaled events" do
|
9
|
+
subject.watch_for("test_event") do |event_name|
|
10
|
+
events_seen << event_name
|
11
|
+
end
|
12
|
+
subject.signal("test_event")
|
13
|
+
expect(events_seen).to eq(%w[test_event])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "does not notify you of events that don't match" do
|
17
|
+
subject.watch_for("match") do |event_name|
|
18
|
+
events_seen << event_name
|
19
|
+
end
|
20
|
+
subject.signal("match")
|
21
|
+
subject.signal("no_match")
|
22
|
+
expect(events_seen).to eq(%w[match])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "understands dynamic event name matchers" do
|
26
|
+
subject.watch_for(/\Achanged:/) do |event_name|
|
27
|
+
events_seen << event_name
|
28
|
+
end
|
29
|
+
subject.signal("changed:font")
|
30
|
+
subject.signal("changed:color")
|
31
|
+
subject.signal("deleted:content")
|
32
|
+
expect(events_seen).to eq(%w[changed:font changed:color])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "passes signaled arguments to the watcher" do
|
36
|
+
subject.watch_for("args") do |event_name, *args|
|
37
|
+
events_seen << args
|
38
|
+
end
|
39
|
+
subject.signal("args")
|
40
|
+
subject.signal("args", 1)
|
41
|
+
subject.signal("args", 2, :three)
|
42
|
+
expect(events_seen).to eq([[ ], [1], [2, :three]])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "notifies all watches of matching events" do
|
46
|
+
subject.watch_for("changed:value") do |event_name|
|
47
|
+
events_seen << "static"
|
48
|
+
end
|
49
|
+
subject.watch_for(/\Achanged:/) do |event_name|
|
50
|
+
events_seen << "dynamic"
|
51
|
+
end
|
52
|
+
subject.signal("changed:value")
|
53
|
+
expect(events_seen.sort).to eq(%w[dynamic static])
|
54
|
+
end
|
55
|
+
|
56
|
+
it "allows you to stop watching for events by identifier" do
|
57
|
+
subject.watch_for("identifiers", identifier: :test_watcher) do |event_name|
|
58
|
+
events_seen << event_name
|
59
|
+
end
|
60
|
+
subject.signal("identifiers")
|
61
|
+
subject.signal("identifiers")
|
62
|
+
subject.stop_watching(:test_watcher)
|
63
|
+
subject.signal("identifiers")
|
64
|
+
expect(events_seen).to eq(%w[identifiers identifiers])
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns autogenerated identifiers" do
|
68
|
+
identifier = subject.watch_for("generated") do |event_name|
|
69
|
+
events_seen << event_name
|
70
|
+
end
|
71
|
+
subject.signal("generated")
|
72
|
+
subject.signal("generated")
|
73
|
+
subject.stop_watching(identifier)
|
74
|
+
subject.signal("generated")
|
75
|
+
expect(events_seen).to eq(%w[generated generated])
|
76
|
+
end
|
77
|
+
|
78
|
+
it "provides a one event shortcut" do
|
79
|
+
subject.watch_for_one("once") do |event_name|
|
80
|
+
events_seen << event_name
|
81
|
+
end
|
82
|
+
subject.signal("once")
|
83
|
+
subject.signal("once")
|
84
|
+
expect(events_seen).to eq(%w[once])
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: signal_lamp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Edward Gray II (JEG2)
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.14'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.14'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ZenTest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rdoc
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.1'
|
83
|
+
description: |
|
84
|
+
This is a system for decoupling objects. Some objects become "signalers" that
|
85
|
+
tell anyone who is interested when "events" happen. Other objects act as
|
86
|
+
"watchers" waiting for and acting on those events.
|
87
|
+
email:
|
88
|
+
- james@graysoftinc.com
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files:
|
92
|
+
- README.md
|
93
|
+
files:
|
94
|
+
- ".gitignore"
|
95
|
+
- ".rspec"
|
96
|
+
- Gemfile
|
97
|
+
- LICENSE
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- lib/signal_lamp.rb
|
101
|
+
- lib/signal_lamp/lamp.rb
|
102
|
+
- lib/signal_lamp/lamp_holder.rb
|
103
|
+
- lib/signal_lamp/version.rb
|
104
|
+
- signal_lamp.gemspec
|
105
|
+
- spec/lamp_holder_spec.rb
|
106
|
+
- spec/lamp_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
homepage: https://github.com/JEG2/signal_lamp
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
112
|
+
post_install_message:
|
113
|
+
rdoc_options:
|
114
|
+
- "--main"
|
115
|
+
- README.md
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.2.2
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: A simple tool for decoupling Ruby object systems.
|
134
|
+
test_files:
|
135
|
+
- spec/lamp_holder_spec.rb
|
136
|
+
- spec/lamp_spec.rb
|
137
|
+
- spec/spec_helper.rb
|