ruby_events 0.0.2 → 0.0.3
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/README.markdown +69 -4
- data/Rakefile +2 -2
- data/lib/ruby_events.rb +36 -8
- metadata +3 -3
data/README.markdown
CHANGED
@@ -10,10 +10,75 @@ objects. It's simple, fast and remains Ruby-ish in style and usage.
|
|
10
10
|
Using ruby_events is simple! Because all objects are automatically extended
|
11
11
|
with the ruby_events functionality, it's as simple as:
|
12
12
|
|
13
|
+
require 'rubygems'
|
13
14
|
require 'ruby_events'
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
class Example
|
17
|
+
def initialize
|
18
|
+
events.listen(:test_event) do |event_data|
|
19
|
+
puts 'Hai there!'
|
20
|
+
puts event_data
|
21
|
+
end
|
22
|
+
end
|
18
23
|
|
19
|
-
|
24
|
+
def call_me
|
25
|
+
events.fire(:test_event, 'My name is Mr Test Man!')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
e = Example.new
|
30
|
+
e.call_me # Fires the event, and our handler gets called!
|
31
|
+
|
32
|
+
You can do cooler and more advanced things, like add listeners to an Array:
|
33
|
+
|
34
|
+
a = []
|
35
|
+
|
36
|
+
class << a
|
37
|
+
alias_method :inject_old, :inject
|
38
|
+
|
39
|
+
def inject(item)
|
40
|
+
events.fire(:injected, self, item)
|
41
|
+
inject_old(item)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
a.events.listen(:injected) do |event_data|
|
46
|
+
puts event_data;
|
47
|
+
end
|
48
|
+
|
49
|
+
a.inject('This is a test')
|
50
|
+
|
51
|
+
But because this is a fairly common pattern, ruby_events does it for you with
|
52
|
+
a little bit of sugar:
|
53
|
+
|
54
|
+
a = []
|
55
|
+
a.events.fire_on_method('<<'.to_sym, :item_injected)
|
56
|
+
a.events.listen(:injected) do |event_data|
|
57
|
+
puts event_data;
|
58
|
+
end
|
59
|
+
|
60
|
+
a << 'this is a test'
|
61
|
+
|
62
|
+
These method events will automatically be passed the arguments that were passed
|
63
|
+
to that method when it was called. Don't let your imagination stop there. You
|
64
|
+
can add an event to any class method, and because all ruby objects are passed by
|
65
|
+
reference, you can set these arguments and change the outcome of the function.
|
66
|
+
Effectively, you can use the events as callbacks on any method:
|
67
|
+
|
68
|
+
a = {:one => 1}
|
69
|
+
b = {:two => 3}
|
70
|
+
|
71
|
+
a.events.fire_on_method(:merge, :merged)
|
72
|
+
a.events.listen(:merged) do |items|
|
73
|
+
# This is the hard part: because the items variable is actually just an
|
74
|
+
# array of all variables passed to the function that fired the event,
|
75
|
+
# you need to access the argument you're interested in; in this case,
|
76
|
+
# Hash.merge only takes one argument, and we'll be using it.
|
77
|
+
items[0][:three] = 3
|
78
|
+
puts 'The hash will have the extra item.'
|
79
|
+
items
|
80
|
+
end
|
81
|
+
|
82
|
+
puts a.merge(b)
|
83
|
+
|
84
|
+
All ruby_events functionality is just an object.events call away.
|
data/Rakefile
CHANGED
@@ -12,11 +12,11 @@ require 'rake/testtask'
|
|
12
12
|
|
13
13
|
spec = Gem::Specification.new do |s|
|
14
14
|
s.name = 'ruby_events'
|
15
|
-
s.version = '0.0.
|
15
|
+
s.version = '0.0.3'
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.extra_rdoc_files = ['README.markdown']
|
18
18
|
s.summary = 'A really simple event implementation that hooks into the Object class. Now all your objects can join in the fun of firing events!'
|
19
|
-
s.description = s.summary
|
19
|
+
s.description = s.summary + ' See http://github.com/nathankleyn/ruby_events for more information.'
|
20
20
|
s.author = 'Nathan Kleyn'
|
21
21
|
s.email = 'nathan@unfinitydesign.com'
|
22
22
|
# s.executables = ['your_executable_here']
|
data/lib/ruby_events.rb
CHANGED
@@ -1,15 +1,18 @@
|
|
1
1
|
module RubyEvents
|
2
2
|
class Events
|
3
|
-
def initialize
|
3
|
+
def initialize(parent)
|
4
|
+
@parent = parent
|
4
5
|
@events = {}
|
5
6
|
end
|
6
7
|
|
7
|
-
def listen(event_type,
|
8
|
+
def listen(event_type, &event)
|
8
9
|
@events[event_type] = [] unless @events.has_key? event_type
|
9
|
-
|
10
|
-
events.each
|
11
|
-
|
12
|
-
|
10
|
+
# TODO: Can we allow both block and an array of Proc's here?
|
11
|
+
# events = [events] unless events.respond_to? :each
|
12
|
+
# events.each do |event|
|
13
|
+
# @events[event_type] << event
|
14
|
+
# end
|
15
|
+
@events[event_type] << event
|
13
16
|
end
|
14
17
|
|
15
18
|
def fire(event_type, *arguments)
|
@@ -19,6 +22,31 @@ module RubyEvents
|
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
25
|
+
|
26
|
+
def fire_on_method(method, event_type, &block)
|
27
|
+
old_method = (method.to_s + '_event_old').to_sym
|
28
|
+
if @parent && @parent.respond_to?(method) && !@parent.respond_to?(old_method)
|
29
|
+
@parent.class.class_eval do
|
30
|
+
alias_method old_method, method
|
31
|
+
end
|
32
|
+
|
33
|
+
# FIXME: Without the internet, this is all I could remember; there is
|
34
|
+
# definitely a better way to do this, so please fix it!
|
35
|
+
#
|
36
|
+
# FIXME: We need to find a way to call the block that's been passed
|
37
|
+
# so they can define the arguments they want to pass to the event.
|
38
|
+
#
|
39
|
+
# We are using self.send instead of calling the method directory because
|
40
|
+
# methods like << can not be resolved as a method properly once they've
|
41
|
+
# had the _event_old suffix tacked on the end.
|
42
|
+
#
|
43
|
+
# Make sure the self.send is at the end, or we won't return what we
|
44
|
+
# are supposed to.
|
45
|
+
@parent.class.class_eval('def ' + method.to_s + '(*args); events.fire(:' + event_type.to_s + ', *args); self.send("' + old_method.to_s + '".to_sym, *args); end')
|
46
|
+
else
|
47
|
+
# TODO: Need to raise exception here.
|
48
|
+
end
|
49
|
+
end
|
22
50
|
|
23
51
|
def remove(event_type, event)
|
24
52
|
if @events.has_key?(event_type)
|
@@ -30,10 +58,10 @@ end
|
|
30
58
|
|
31
59
|
class Object
|
32
60
|
def events
|
33
|
-
@events || @events = RubyEvents::Events.new
|
61
|
+
@events || @events = RubyEvents::Events.new(self)
|
34
62
|
end
|
35
63
|
|
36
64
|
def events=(events)
|
37
65
|
@events = events
|
38
66
|
end
|
39
|
-
end
|
67
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nathan Kleyn
|
@@ -18,7 +18,7 @@ date: 2010-04-26 00:00:00 +01:00
|
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
|
-
description: A really simple event implementation that hooks into the Object class. Now all your objects can join in the fun of firing events!
|
21
|
+
description: A really simple event implementation that hooks into the Object class. Now all your objects can join in the fun of firing events! See http://github.com/nathankleyn/ruby_events for more information.
|
22
22
|
email: nathan@unfinitydesign.com
|
23
23
|
executables: []
|
24
24
|
|