rbevents 0.1.0 → 1.0.0
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 +4 -4
- data/.gitignore +18 -18
- data/Gemfile +1 -1
- data/README.md +43 -40
- data/lib/events.rb +119 -119
- data/rakefile +15 -15
- data/rbevents.gemspec +24 -24
- data/test/test_events.rb +51 -51
- data/test/test_example.rb +29 -29
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b4bfd418d2b7bb1a9498a476e928b14b24a62f2
|
4
|
+
data.tar.gz: 35c34018c0886e3dfd67d29eb5a66265c0bed8ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77d19532e77ff61fb62417d8590a305d61ceb840918429730fd806573e63b3eaa54914df1ea178d26dcbd379b9072b807f930edfef5f93cf1636ed2d14d9e514
|
7
|
+
data.tar.gz: e5d1f44f51e3dd97565a585dbc3ad1e78439bb0ee9f6f02726f96e4ff53982b8c0cb2a7ca00b914f955da21797b99eb996bb4d67e4124f88b7fccbdb88f8a623
|
data/.gitignore
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
coverage
|
6
|
-
InstalledFiles
|
7
|
-
lib/bundler/man
|
8
|
-
pkg
|
9
|
-
rdoc
|
10
|
-
spec/reports
|
11
|
-
test/tmp
|
12
|
-
test/version_tmp
|
13
|
-
tmp
|
14
|
-
|
15
|
-
# YARD artifacts
|
16
|
-
.yardoc
|
17
|
-
_yardoc
|
18
|
-
doc/
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
|
15
|
+
# YARD artifacts
|
16
|
+
.yardoc
|
17
|
+
_yardoc
|
18
|
+
doc/
|
data/Gemfile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
gemspec
|
1
|
+
gemspec
|
data/README.md
CHANGED
@@ -1,40 +1,43 @@
|
|
1
|
-
rbevents
|
2
|
-
========
|
3
|
-
|
4
|
-
It's like Observable, but better.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
1
|
+
rbevents
|
2
|
+
========
|
3
|
+
|
4
|
+
It's like Observable, but better.
|
5
|
+
|
6
|
+
[](http://badge.fury.io/rb/rbevents) [](https://codeclimate.com/github/jonnyarnold/rbevents)
|
7
|
+
|
8
|
+
Example
|
9
|
+
=======
|
10
|
+
```ruby
|
11
|
+
|
12
|
+
# Let's define a class with subscribable events
|
13
|
+
class EventsExample
|
14
|
+
include Events # Mix in the magic
|
15
|
+
|
16
|
+
# Define an event
|
17
|
+
event :activation
|
18
|
+
|
19
|
+
# Here, we define a method that fires the event
|
20
|
+
def activate
|
21
|
+
# Event.fire sets off the event and collects
|
22
|
+
# any return values from subscribed events
|
23
|
+
return_values = @activation.fire
|
24
|
+
return_values
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Let's build an object...
|
29
|
+
example = EventsExample.new
|
30
|
+
|
31
|
+
# ...and then add some subscribers
|
32
|
+
example.on_activation do
|
33
|
+
"Hello"
|
34
|
+
end
|
35
|
+
example.on_activation do
|
36
|
+
"World!"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Finally, we call a method which alerts the subscribers
|
40
|
+
example.activate # => ["Hello", "World!"]
|
41
|
+
```
|
42
|
+
|
43
|
+
Anything else? Check the code.
|
data/lib/events.rb
CHANGED
@@ -1,119 +1,119 @@
|
|
1
|
-
# Mixin for event-driven programming.
|
2
|
-
#
|
3
|
-
# The mixin adds the following:
|
4
|
-
# - <tt>event [sym]</tt>: Creates an +Event+ with the given name
|
5
|
-
# - <tt>singleton_event [sym]</tt>: Creates a +SingleSubscriberEvent+ with the given name
|
6
|
-
# Note that the command <tt>event :abc</tt> adds an alias, <tt>on_abc</tt>, for adding event callbacks
|
7
|
-
#
|
8
|
-
# == Example
|
9
|
-
# See README
|
10
|
-
#
|
11
|
-
# == License
|
12
|
-
# If you use this, let me know? jonny.arnold89@gmail.com. Thanks.
|
13
|
-
module Events
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
1
|
+
# Mixin for event-driven programming.
|
2
|
+
#
|
3
|
+
# The mixin adds the following:
|
4
|
+
# - <tt>event [sym]</tt>: Creates an +Event+ with the given name
|
5
|
+
# - <tt>singleton_event [sym]</tt>: Creates a +SingleSubscriberEvent+ with the given name
|
6
|
+
# Note that the command <tt>event :abc</tt> adds an alias, <tt>on_abc</tt>, for adding event callbacks
|
7
|
+
#
|
8
|
+
# == Example
|
9
|
+
# See README
|
10
|
+
#
|
11
|
+
# == License
|
12
|
+
# If you use this, let me know? jonny.arnold89@gmail.com. Thanks.
|
13
|
+
module Events
|
14
|
+
|
15
|
+
# Version number
|
16
|
+
# Uses Semantic Versioning: http://semver.org/
|
17
|
+
VERSION = '1.0.0'
|
18
|
+
|
19
|
+
# An event that can be subscribed to,
|
20
|
+
# and runs any subscribed callback when
|
21
|
+
# it is fired.
|
22
|
+
class Event
|
23
|
+
# Gets the collection of callbacks subscribed to this event.
|
24
|
+
attr_accessor :callbacks
|
25
|
+
|
26
|
+
# Class initializer
|
27
|
+
def initialize
|
28
|
+
@callbacks = []
|
29
|
+
end
|
30
|
+
|
31
|
+
# Called when the event occurs
|
32
|
+
# [*arguments] The arguments to pass to each callback
|
33
|
+
# Returns any values returned by any subscribed callback
|
34
|
+
def fire(*arguments)
|
35
|
+
return_values = []
|
36
|
+
|
37
|
+
@callbacks.each do |proc|
|
38
|
+
return_values << proc.call(*arguments)
|
39
|
+
end
|
40
|
+
|
41
|
+
return_values
|
42
|
+
end
|
43
|
+
|
44
|
+
# Adds a callback to the event
|
45
|
+
# [proc] The block to execute
|
46
|
+
def add_callback(&proc)
|
47
|
+
@callbacks << proc
|
48
|
+
end
|
49
|
+
|
50
|
+
# Removes the given block from the event
|
51
|
+
# [proc] The block to remove
|
52
|
+
def remove_callback(&proc)
|
53
|
+
@callbacks.delete proc
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# An event with a single subscriber
|
58
|
+
class SingleSubscriberEvent < Event
|
59
|
+
|
60
|
+
# Override of Event.add_callback
|
61
|
+
def add_callback(&proc)
|
62
|
+
if callbacks.length == 1
|
63
|
+
raise EventSubscriptionError, "Cannot add more than one callback to SingleSubscriberEvent"
|
64
|
+
end
|
65
|
+
|
66
|
+
super
|
67
|
+
end
|
68
|
+
|
69
|
+
# Override of Event.fire
|
70
|
+
def fire(*args)
|
71
|
+
packed_result = super
|
72
|
+
if packed_result.length == 0
|
73
|
+
return nil
|
74
|
+
else
|
75
|
+
return packed_result.first
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Denotes an error with event subscription
|
81
|
+
class EventSubscriptionError < StandardError
|
82
|
+
end
|
83
|
+
|
84
|
+
# :nodoc:
|
85
|
+
def self.append_features(cls)
|
86
|
+
# Create an event
|
87
|
+
# [sym] The name to assign to the event
|
88
|
+
# Retrieve via .sym
|
89
|
+
def cls.event(sym)
|
90
|
+
variable_name = "@#{sym}"
|
91
|
+
|
92
|
+
define_method(sym.to_s) do
|
93
|
+
if not instance_variable_defined? variable_name then
|
94
|
+
instance_variable_set variable_name, Event.new
|
95
|
+
end
|
96
|
+
instance_variable_get variable_name
|
97
|
+
end
|
98
|
+
|
99
|
+
firealias = "on_#{sym}"
|
100
|
+
define_method(firealias) do |&proc|
|
101
|
+
if not instance_variable_defined? variable_name then
|
102
|
+
instance_variable_set variable_name, Event.new
|
103
|
+
end
|
104
|
+
event_obj = instance_variable_get variable_name
|
105
|
+
event_obj.add_callback &proc
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def cls.singleton_event(sym)
|
110
|
+
define_method(sym.to_s) do
|
111
|
+
variable_name = "@#{sym}"
|
112
|
+
if not instance_variable_defined? variable_name then
|
113
|
+
instance_variable_set variable_name, SingleSubscriberEvent.new
|
114
|
+
end
|
115
|
+
instance_variable_get variable_name
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/rakefile
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'rake/testtask'
|
2
|
-
require 'rdoc/task'
|
3
|
-
|
4
|
-
task :default => :test
|
5
|
-
|
6
|
-
Rake::TestTask.new do |t|
|
7
|
-
t.libs << "test"
|
8
|
-
t.test_files = FileList['test/test*.rb']
|
9
|
-
t.verbose = true
|
10
|
-
end
|
11
|
-
|
12
|
-
Rake::RDocTask.new do |rd|
|
13
|
-
rd.main = "README.md"
|
14
|
-
rd.rdoc_files.include "lib/**.rb"
|
15
|
-
end
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'rdoc/task'
|
3
|
+
|
4
|
+
task :default => :test
|
5
|
+
|
6
|
+
Rake::TestTask.new do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.test_files = FileList['test/test*.rb']
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::RDocTask.new do |rd|
|
13
|
+
rd.main = "README.md"
|
14
|
+
rd.rdoc_files.include "lib/**.rb"
|
15
|
+
end
|
data/rbevents.gemspec
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../lib/events', __FILE__)
|
4
|
-
|
5
|
-
Gem::Specification.new do |gem|
|
6
|
-
gem.name = "rbevents"
|
7
|
-
gem.version = Events::VERSION
|
8
|
-
gem.summary = %q{Events for Ruby}
|
9
|
-
gem.description = %q{Provides an Event mixin for enabling classes to create events for public and private subscription.}
|
10
|
-
gem.license = "GPL"
|
11
|
-
gem.authors = ["Jonny Arnold"]
|
12
|
-
gem.email = "jonny.arnold89@gmail.com"
|
13
|
-
gem.homepage = "https://github.com/jonnyarnold/rbevents"
|
14
|
-
|
15
|
-
gem.files = `git ls-files`.split($/)
|
16
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
-
gem.require_paths = ['lib']
|
19
|
-
|
20
|
-
gem.add_development_dependency 'bundler', '~> 1.0'
|
21
|
-
gem.add_development_dependency 'rake', '~> 0.8'
|
22
|
-
gem.add_development_dependency 'rdoc', '~> 3.0'
|
23
|
-
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
24
|
-
end
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require File.expand_path('../lib/events', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = "rbevents"
|
7
|
+
gem.version = Events::VERSION
|
8
|
+
gem.summary = %q{Events for Ruby}
|
9
|
+
gem.description = %q{Provides an Event mixin for enabling classes to create events for public and private subscription.}
|
10
|
+
gem.license = "GPL"
|
11
|
+
gem.authors = ["Jonny Arnold"]
|
12
|
+
gem.email = "jonny.arnold89@gmail.com"
|
13
|
+
gem.homepage = "https://github.com/jonnyarnold/rbevents"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_development_dependency 'bundler', '~> 1.0'
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.8'
|
22
|
+
gem.add_development_dependency 'rdoc', '~> 3.0'
|
23
|
+
gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
|
24
|
+
end
|
data/test/test_events.rb
CHANGED
@@ -1,52 +1,52 @@
|
|
1
|
-
require "./lib/events"
|
2
|
-
require "test/unit"
|
3
|
-
|
4
|
-
class ClassWithEvents
|
5
|
-
include Events
|
6
|
-
event :test_event
|
7
|
-
singleton_event :test_singleton_event
|
8
|
-
end
|
9
|
-
|
10
|
-
class EventDrivenTest < Test::Unit::TestCase
|
11
|
-
|
12
|
-
def setup
|
13
|
-
@test_object = ClassWithEvents.new
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_can_subscribe_to_event
|
17
|
-
@test_object.test_event.add_callback { puts "Hello!" }
|
18
|
-
|
19
|
-
assert @test_object.test_event.callbacks.length == 1
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_event_can_return_values
|
23
|
-
@test_object.test_event.add_callback { return 1 }
|
24
|
-
|
25
|
-
results = @test_object.test_event.fire
|
26
|
-
assert results == [1]
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_single_subscriber_event_raises_error_on_second_callback
|
30
|
-
assert_nothing_raised do
|
31
|
-
@test_object.test_singleton_event.add_callback { puts "Hello!" }
|
32
|
-
end
|
33
|
-
|
34
|
-
assert_raises(Events::EventSubscriptionError) do
|
35
|
-
@test_object.test_singleton_event.add_callback { puts "Hello again!" }
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_event_fire_alias
|
40
|
-
@test_object.on_test_event { puts "Hello" }
|
41
|
-
assert @test_object.test_event.callbacks.length == 1
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_event_can_be_given_arguments
|
45
|
-
@test_object.on_test_event do |arg|
|
46
|
-
arg
|
47
|
-
end
|
48
|
-
|
49
|
-
results = @test_object.test_event.fire("abc")
|
50
|
-
assert results == ["abc"]
|
51
|
-
end
|
1
|
+
require "./lib/events"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
class ClassWithEvents
|
5
|
+
include Events
|
6
|
+
event :test_event
|
7
|
+
singleton_event :test_singleton_event
|
8
|
+
end
|
9
|
+
|
10
|
+
class EventDrivenTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@test_object = ClassWithEvents.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_can_subscribe_to_event
|
17
|
+
@test_object.test_event.add_callback { puts "Hello!" }
|
18
|
+
|
19
|
+
assert @test_object.test_event.callbacks.length == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_event_can_return_values
|
23
|
+
@test_object.test_event.add_callback { return 1 }
|
24
|
+
|
25
|
+
results = @test_object.test_event.fire
|
26
|
+
assert results == [1]
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_single_subscriber_event_raises_error_on_second_callback
|
30
|
+
assert_nothing_raised do
|
31
|
+
@test_object.test_singleton_event.add_callback { puts "Hello!" }
|
32
|
+
end
|
33
|
+
|
34
|
+
assert_raises(Events::EventSubscriptionError) do
|
35
|
+
@test_object.test_singleton_event.add_callback { puts "Hello again!" }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_event_fire_alias
|
40
|
+
@test_object.on_test_event { puts "Hello" }
|
41
|
+
assert @test_object.test_event.callbacks.length == 1
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_event_can_be_given_arguments
|
45
|
+
@test_object.on_test_event do |arg|
|
46
|
+
arg
|
47
|
+
end
|
48
|
+
|
49
|
+
results = @test_object.test_event.fire("abc")
|
50
|
+
assert results == ["abc"]
|
51
|
+
end
|
52
52
|
end
|
data/test/test_example.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
require "./lib/events"
|
2
|
-
require "test/unit"
|
3
|
-
|
4
|
-
# Test class in example
|
5
|
-
class EventsExample
|
6
|
-
include Events
|
7
|
-
event :activation
|
8
|
-
|
9
|
-
def activate
|
10
|
-
return_values = @activation.fire
|
11
|
-
return_values
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Test usage in example
|
16
|
-
class ExampleTests < Test::Unit::TestCase
|
17
|
-
def test_example_executes_correctly
|
18
|
-
example = EventsExample.new
|
19
|
-
|
20
|
-
example.on_activation do
|
21
|
-
"Hello"
|
22
|
-
end
|
23
|
-
|
24
|
-
example.on_activation do
|
25
|
-
"World!"
|
26
|
-
end
|
27
|
-
|
28
|
-
assert example.activate == ["Hello", "World!"]
|
29
|
-
end
|
1
|
+
require "./lib/events"
|
2
|
+
require "test/unit"
|
3
|
+
|
4
|
+
# Test class in example
|
5
|
+
class EventsExample
|
6
|
+
include Events
|
7
|
+
event :activation
|
8
|
+
|
9
|
+
def activate
|
10
|
+
return_values = @activation.fire
|
11
|
+
return_values
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Test usage in example
|
16
|
+
class ExampleTests < Test::Unit::TestCase
|
17
|
+
def test_example_executes_correctly
|
18
|
+
example = EventsExample.new
|
19
|
+
|
20
|
+
example.on_activation do
|
21
|
+
"Hello"
|
22
|
+
end
|
23
|
+
|
24
|
+
example.on_activation do
|
25
|
+
"World!"
|
26
|
+
end
|
27
|
+
|
28
|
+
assert example.activate == ["Hello", "World!"]
|
29
|
+
end
|
30
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbevents
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonny Arnold
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
101
|
version: '0'
|
102
102
|
requirements: []
|
103
103
|
rubyforge_project:
|
104
|
-
rubygems_version: 2.
|
104
|
+
rubygems_version: 2.2.2
|
105
105
|
signing_key:
|
106
106
|
specification_version: 4
|
107
107
|
summary: Events for Ruby
|