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.
Files changed (4) hide show
  1. data/README.markdown +69 -4
  2. data/Rakefile +2 -2
  3. data/lib/ruby_events.rb +36 -8
  4. 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
- x = Object.new
16
- x.events.listen :test_event, Proc.new {|data_passed| puts 'hai!'; puts data_passed }
17
- x.events.fire :test_event, :test_data => 'hello', :more_test_data => 'hey'
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
- All ruby_events functionality is just an object.events call away.
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.2'
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, events)
8
+ def listen(event_type, &event)
8
9
  @events[event_type] = [] unless @events.has_key? event_type
9
- events = [events] unless events.respond_to? :each
10
- events.each do |event|
11
- @events[event_type] << event
12
- end
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
- - 2
9
- version: 0.0.2
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