ruby_events 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|