ventable 0.0.2
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.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Guardfile +15 -0
- data/LICENSE +22 -0
- data/README.md +116 -0
- data/Rakefile +3 -0
- data/lib/ventable.rb +15 -0
- data/lib/ventable/event.rb +86 -0
- data/lib/ventable/version.rb +3 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/ventable/ventable_spec.rb +169 -0
- data/ventable.gemspec +22 -0
- metadata +110 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#^syntax detection
|
3
|
+
|
4
|
+
# A sample Guardfile
|
5
|
+
# More info at https://github.com/guard/guard#readme
|
6
|
+
|
7
|
+
guard 'rspec' do
|
8
|
+
watch(%r{^ventable\.gemspec}) { "spec"}
|
9
|
+
watch(%r{^lib/(.+)\.rb$}) { "spec" }
|
10
|
+
|
11
|
+
watch(%r{^spec/.+_spec\.rb$})
|
12
|
+
watch('spec/spec_helper.rb') { "spec" }
|
13
|
+
watch(%r{spec/support/.*}) { "spec" }
|
14
|
+
end
|
15
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Konstantin Gredeskoul
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
[](http://travis-ci.org/kigster/ventable)
|
2
|
+
|
3
|
+
# Ventable
|
4
|
+
|
5
|
+
Simple eventing gem that implements Observable pattern, but with more options, ability to group observers and wrap
|
6
|
+
them in arbitrary blocks of code. For example, when a certain event fires, some observers may be called within
|
7
|
+
a transaction context, while others maybe called outside of the transaction context.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'ventable'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install ventable
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
1. Create your own plain ruby class that optionally carries some data important to the event. Include module Ventable::Event.
|
26
|
+
2. Create one or more observers. Observer can be any class that implements event handler method as a class method, such as a
|
27
|
+
generic method ```self.handle_event(event)``` or a more specific method mapped to the event name: say for event UserRegistered the
|
28
|
+
callback event would be ```self.handle_user_registered_event(event)```
|
29
|
+
3. Register your observers with the event using ```notifies``` event method, or register groups using ```group``` method, and then
|
30
|
+
use ```notify``` with options ```inside: :group_name```
|
31
|
+
4. Instantiate your event (optionally with data), and call fire!() method.
|
32
|
+
|
33
|
+
## Example
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'ventable'
|
37
|
+
|
38
|
+
# this is a custom Event class that has some data associated with it
|
39
|
+
|
40
|
+
class AlarmSoundEvent
|
41
|
+
include Ventable::Event
|
42
|
+
attr_accessor :wakeup_time
|
43
|
+
|
44
|
+
def initialize(wakeup_time)
|
45
|
+
@wakeup_time = wakeup_time
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# This class is an observer, interested in WakeUpEvents.
|
50
|
+
class SleepingPerson
|
51
|
+
def self.handle_wake_up_event(event)
|
52
|
+
self.wake_up
|
53
|
+
puts "snoozing at #{event.wakeup_time}"
|
54
|
+
self.snooze(5)
|
55
|
+
end
|
56
|
+
#.. implementation
|
57
|
+
end
|
58
|
+
|
59
|
+
# Register the observer
|
60
|
+
AlarmSoundEvent.notifies SleepingPerson
|
61
|
+
|
62
|
+
# Create and fire the event
|
63
|
+
AlarmSoundEvent.new(Date.new).fire!
|
64
|
+
```
|
65
|
+
|
66
|
+
## Using #configure and groups
|
67
|
+
|
68
|
+
|
69
|
+
Events can be configured to call observers in groups, with an optional block around it.
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
|
73
|
+
transaction = ->(b){
|
74
|
+
ActiveRecord::Base.transaction do
|
75
|
+
b.call
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
class SomeEvent
|
80
|
+
include Ventable::Event
|
81
|
+
end
|
82
|
+
|
83
|
+
SomeEvent.configure do
|
84
|
+
# first observer to be called
|
85
|
+
notifies FirstObserverClassToBeCalled
|
86
|
+
|
87
|
+
# this group will be notified next
|
88
|
+
group :transaction, &transaction
|
89
|
+
|
90
|
+
# this block is executed after the group
|
91
|
+
notifies inside: :transaction do
|
92
|
+
# perform block
|
93
|
+
end
|
94
|
+
|
95
|
+
# these observers are run inside the transaction block
|
96
|
+
notifies ObserverClass1, ObserverClass2, inside: :transaction
|
97
|
+
|
98
|
+
# this one is the last to be notified
|
99
|
+
notifies AnotherObserverClass
|
100
|
+
end
|
101
|
+
|
102
|
+
SomeEvent.new.fire!
|
103
|
+
|
104
|
+
```
|
105
|
+
|
106
|
+
## Contributing
|
107
|
+
|
108
|
+
1. Fork it
|
109
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
110
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
111
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
112
|
+
5. Create new Pull Request
|
113
|
+
|
114
|
+
## Author
|
115
|
+
|
116
|
+
Konstantin Gredeskoul, @kig, http://github.com/kigster
|
data/Rakefile
ADDED
data/lib/ventable.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "ventable/version"
|
2
|
+
require "ventable/event"
|
3
|
+
|
4
|
+
module Ventable
|
5
|
+
end
|
6
|
+
|
7
|
+
class String
|
8
|
+
def underscore
|
9
|
+
self.gsub(/::/, '/').
|
10
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
11
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
12
|
+
tr("-", "_").
|
13
|
+
downcase
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module ::Ventable
|
4
|
+
module Event
|
5
|
+
def self.included(klazz)
|
6
|
+
klazz.instance_eval do
|
7
|
+
@observers = Set.new
|
8
|
+
class << self
|
9
|
+
attr_accessor :observers
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
klazz.extend ClassMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
def fire!
|
17
|
+
notify_observer_set(self.class.observers)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def notify_observer_set(observer_set)
|
23
|
+
observer_set.each do |observer_entry|
|
24
|
+
if observer_entry.is_a?(Hash)
|
25
|
+
around_block = observer_entry[:around_block]
|
26
|
+
inside_block = -> { notify_observer_set(observer_entry[:observers]) }
|
27
|
+
around_block.call(inside_block)
|
28
|
+
else
|
29
|
+
notify_observer(observer_entry)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def notify_observer(observer)
|
35
|
+
case observer
|
36
|
+
when Proc
|
37
|
+
observer.call(self)
|
38
|
+
else # class
|
39
|
+
notify_class_observer(observer)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def notify_class_observer(observer)
|
44
|
+
observer.respond_to?(self.class.default_callback_method) ?
|
45
|
+
observer.send(self.class.default_callback_method, self) :
|
46
|
+
observer.send(:handle_event, self)
|
47
|
+
end
|
48
|
+
|
49
|
+
module ClassMethods
|
50
|
+
def configure(&block)
|
51
|
+
class_eval(&block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def notifies(*observer_list, &block)
|
55
|
+
options = {}
|
56
|
+
options.merge! observer_list.pop if observer_list.last.is_a?(Hash)
|
57
|
+
observer_set = self.observers
|
58
|
+
if options[:inside]
|
59
|
+
observer_entry = self.find_observer_group(options[:inside])
|
60
|
+
observer_set = observer_entry[:observers]
|
61
|
+
end
|
62
|
+
observer_list.each { |o| observer_set << o } unless observer_list.empty?
|
63
|
+
observer_set << block if block
|
64
|
+
end
|
65
|
+
|
66
|
+
def group(name, &block)
|
67
|
+
raise "Group #{name} already defined by #{g}" if find_observer_group(name)
|
68
|
+
self.observers <<
|
69
|
+
{ name: name,
|
70
|
+
around_block: block,
|
71
|
+
observers: Set.new
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_observer_group(name)
|
76
|
+
self.observers.find { |o| o.is_a?(Hash) && o[:name] == name }
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_callback_method
|
80
|
+
target = self
|
81
|
+
method = "handle_" + target.name.gsub(/.*::/,'').underscore.gsub(/_event/, '') + "_event"
|
82
|
+
method.to_sym
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
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
|
+
|
8
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
9
|
+
require 'rubygems'
|
10
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
11
|
+
require 'ventable'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
|
18
|
+
# Run specs in random order to surface order dependencies. If you find an
|
19
|
+
# order dependency and want to debug it, you can fix the order by providing
|
20
|
+
# the seed, which is printed after each run.
|
21
|
+
# --seed 1234
|
22
|
+
config.order = 'random'
|
23
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require 'ventable'
|
2
|
+
require 'pp'
|
3
|
+
describe Ventable do
|
4
|
+
before do
|
5
|
+
class TestEvent
|
6
|
+
include Ventable::Event
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "including Ventable::Event" do
|
11
|
+
it "should create a class instance variable to keep observers" do
|
12
|
+
TestEvent.observers.should_not be_nil
|
13
|
+
TestEvent.observers.should be_a(Set)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should see observers variable from instance methods" do
|
17
|
+
observers = nil
|
18
|
+
TestEvent.new.instance_eval do
|
19
|
+
observers = self.class.observers
|
20
|
+
end
|
21
|
+
observers.should_not be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should maintain separate sets of observers for each event" do
|
25
|
+
class AnotherEvent
|
26
|
+
include Ventable::Event
|
27
|
+
end
|
28
|
+
AnotherEvent.observers.object_id.should_not == TestEvent.observers.object_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#fire" do
|
33
|
+
before do
|
34
|
+
class TestEvent
|
35
|
+
include Ventable::Event
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should properly call a Proc observer" do
|
40
|
+
run_block = false
|
41
|
+
event = nil
|
42
|
+
TestEvent.notifies do |e|
|
43
|
+
run_block = true
|
44
|
+
event = e
|
45
|
+
end
|
46
|
+
run_block.should_not be_true
|
47
|
+
event.should be_nil
|
48
|
+
|
49
|
+
# fire the event
|
50
|
+
TestEvent.new.fire!
|
51
|
+
|
52
|
+
run_block.should be_true
|
53
|
+
event.should_not be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should properly call a class observer" do
|
57
|
+
TestEvent.instance_eval do
|
58
|
+
class << self
|
59
|
+
attr_accessor :flag
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
TestEvent.class_eval do
|
64
|
+
def set_flag!
|
65
|
+
self.class.flag = true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
class TestEventObserver
|
69
|
+
def self.handle_test_event event
|
70
|
+
event.set_flag!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
TestEvent.notifies TestEventObserver
|
74
|
+
TestEvent.flag.should be_false
|
75
|
+
|
76
|
+
TestEvent.new.fire!
|
77
|
+
TestEvent.flag.should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should properly call a group of observers" do
|
81
|
+
transaction_called = false
|
82
|
+
transaction_completed = false
|
83
|
+
transaction = ->(observer_block) {
|
84
|
+
transaction_called = true
|
85
|
+
observer_block.call
|
86
|
+
transaction_completed = true
|
87
|
+
}
|
88
|
+
|
89
|
+
TestEvent.group :transaction, &transaction
|
90
|
+
observer_block_called = false
|
91
|
+
|
92
|
+
# this flag ensures that this block really runs inside
|
93
|
+
# the transaction group block
|
94
|
+
transaction_already_completed = false
|
95
|
+
event_inside = nil
|
96
|
+
TestEvent.notifies inside: :transaction do |event|
|
97
|
+
observer_block_called = true
|
98
|
+
transaction_already_completed = transaction_completed
|
99
|
+
event_inside = event
|
100
|
+
end
|
101
|
+
|
102
|
+
transaction_called.should be_false
|
103
|
+
transaction_already_completed.should be_false
|
104
|
+
observer_block_called.should be_false
|
105
|
+
|
106
|
+
TestEvent.new.fire!
|
107
|
+
|
108
|
+
transaction_called.should be_true
|
109
|
+
observer_block_called.should be_true
|
110
|
+
transaction_already_completed.should be_false
|
111
|
+
event_inside.should_not be_nil
|
112
|
+
event_inside.should be_a(TestEvent)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#default_callback_method" do
|
117
|
+
before do
|
118
|
+
class SomeAwesomeEvent
|
119
|
+
include Ventable::Event
|
120
|
+
end
|
121
|
+
|
122
|
+
module Blah
|
123
|
+
class AnotherSweetEvent
|
124
|
+
include Ventable::Event
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class SomeOtherStuffHappened
|
129
|
+
include Ventable::Event
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should properly set the callback method name" do
|
134
|
+
SomeAwesomeEvent.default_callback_method.should == :handle_some_awesome_event
|
135
|
+
Blah::AnotherSweetEvent.default_callback_method.should == :handle_another_sweet_event
|
136
|
+
SomeOtherStuffHappened.default_callback_method.should == :handle_some_other_stuff_happened_event
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#configure" do
|
141
|
+
it "properly configures the event with observesrs" do
|
142
|
+
notified_observer = false
|
143
|
+
TestEvent.configure do
|
144
|
+
notifies do
|
145
|
+
notified_observer = true
|
146
|
+
end
|
147
|
+
end
|
148
|
+
TestEvent.new.fire!
|
149
|
+
notified_observer.should be_true
|
150
|
+
end
|
151
|
+
|
152
|
+
it "configures observers with groups" do
|
153
|
+
notified_observer = false
|
154
|
+
called_transaction = false
|
155
|
+
TestEvent.configure do
|
156
|
+
group :transaction, &->(b){
|
157
|
+
b.call
|
158
|
+
called_transaction = true
|
159
|
+
}
|
160
|
+
notifies inside: :transaction do
|
161
|
+
notified_observer = true
|
162
|
+
end
|
163
|
+
end
|
164
|
+
TestEvent.new.fire!
|
165
|
+
notified_observer.should be_true
|
166
|
+
called_transaction.should be_true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
data/ventable.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
require File.expand_path('../lib/ventable/version', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.authors = ["Konstantin Gredeskoul"]
|
7
|
+
gem.email = ["kigster@gmail.com"]
|
8
|
+
gem.description = %q{Event/Observable design pattern in ruby}
|
9
|
+
gem.summary = %q{Event/Observable design pattern in ruby}
|
10
|
+
gem.homepage = "https://github.com/kigster/ventable"
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($\)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "ventable"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = Ventable::VERSION
|
18
|
+
|
19
|
+
gem.add_development_dependency "rspec"
|
20
|
+
gem.add_development_dependency "rspec-mocks"
|
21
|
+
gem.add_development_dependency 'guard-rspec'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ventable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Konstantin Gredeskoul
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec-mocks
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: guard-rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Event/Observable design pattern in ruby
|
63
|
+
email:
|
64
|
+
- kigster@gmail.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- .gitignore
|
70
|
+
- .rspec
|
71
|
+
- .travis.yml
|
72
|
+
- Gemfile
|
73
|
+
- Guardfile
|
74
|
+
- LICENSE
|
75
|
+
- README.md
|
76
|
+
- Rakefile
|
77
|
+
- lib/ventable.rb
|
78
|
+
- lib/ventable/event.rb
|
79
|
+
- lib/ventable/version.rb
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
- spec/ventable/ventable_spec.rb
|
82
|
+
- ventable.gemspec
|
83
|
+
homepage: https://github.com/kigster/ventable
|
84
|
+
licenses: []
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ! '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ! '>='
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.8.24
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: Event/Observable design pattern in ruby
|
107
|
+
test_files:
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
- spec/ventable/ventable_spec.rb
|
110
|
+
has_rdoc:
|