Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #1 from ttencate/master

unsubscribe_all method, a nice alias, and whitespace fixes
  • Loading branch information...
commit 84abc318a41b4464a08bcc5291d3b47e202e517e 2 parents 5a5ae54 + 2426e3b
@shawn42 shawn42 authored
Showing with 97 additions and 59 deletions.
  1. +70 −59 lib/publisher.rb
  2. +27 −0 test/publisher_test.rb
View
129 lib/publisher.rb
@@ -1,15 +1,15 @@
-# See README.rdoc for synopsis
+# See README.rdoc for synopsis
module Publisher
- # Use this method (or one of the aliases) to declare which events you support
- # Once invoked, your class will have the neccessary supporting methods for subscribing and firing.
- def has_events(*args)
- include InstanceMethods unless @published_events
- @published_events ||= []
- @published_events << args
- @published_events.flatten!
- end
- alias :has_event :has_events
- alias :can_fire :has_events
+ # Use this method (or one of the aliases) to declare which events you support
+ # Once invoked, your class will have the neccessary supporting methods for subscribing and firing.
+ def has_events(*args)
+ include InstanceMethods unless @published_events
+ @published_events ||= []
+ @published_events << args
+ @published_events.flatten!
+ end
+ alias :has_event :has_events
+ alias :can_fire :has_events
def published_events
return @published_events if @published_events == :any_event_is_ok
@@ -24,42 +24,42 @@ def published_events
my_events
end
- # Use this method to allow subscription and firing of arbitrary events.
- # This is convenient if, eg, your class has dynamic event names.
- # Don't use this unless you have to; it's better to declare your events if you
- # can.
- def has_any_event
- include InstanceMethods unless @published_events
- @published_events = :any_event_is_ok
- end
- alias :can_fire_anything :has_any_event
-
- # Container for the instance methods that will be mixed-in to extenders of Publisher.
- # These methods get mixed in when you use the 'has_events' call.
- module InstanceMethods
- # Sign up a code block to be executed when an event is fired.
- # It's important to know the signature of the event, as your proc needs
- # to accept incoming parameters accordingly.
- def subscribe(event, target=nil, callback=nil, &block)
- ensure_valid event
- @subscriptions ||= {}
- listeners = @subscriptions[event]
- listeners ||= []
+ # Use this method to allow subscription and firing of arbitrary events.
+ # This is convenient if, eg, your class has dynamic event names.
+ # Don't use this unless you have to; it's better to declare your events if you
+ # can.
+ def has_any_event
+ include InstanceMethods unless @published_events
+ @published_events = :any_event_is_ok
+ end
+ alias :can_fire_anything :has_any_event
+
+ # Container for the instance methods that will be mixed-in to extenders of Publisher.
+ # These methods get mixed in when you use the 'has_events' call.
+ module InstanceMethods
+ # Sign up a code block to be executed when an event is fired.
+ # It's important to know the signature of the event, as your proc needs
+ # to accept incoming parameters accordingly.
+ def subscribe(event, target=nil, callback=nil, &block)
+ ensure_valid event
+ @subscriptions ||= {}
+ listeners = @subscriptions[event]
+ listeners ||= []
if target && callback
listeners << [target, callback]
else
listeners << block
end
- @subscriptions[event] = listeners
- end
- alias :when :subscribe
- alias :on :subscribe
-
- # Unsubscribe for an event. 'listener' is a reference to the object who enacted the
- # subscription... often, this is 'self'. If this object has subsribed more than once
+ @subscriptions[event] = listeners
+ end
+ alias :when :subscribe
+ alias :on :subscribe
+
+ # Unsubscribe for an event. 'listener' is a reference to the object who enacted the
+ # subscription... often, this is 'self'. If this object has subsribed more than once
# for the given event (unusual), all of the subscriptions will be removed.
def unsubscribe(event, listener)
- ensure_valid event
+ ensure_valid event
if @subscriptions && @subscriptions[event]
@subscriptions[event].delete_if do |block_or_target|
if block_or_target.is_a? Proc
@@ -70,30 +70,41 @@ def unsubscribe(event, listener)
end
end
end
+ alias :off :unsubscribe
+
+ # Unsubscribe from all events. Like calling 'unsubscribe' for all events that
+ # 'listener' has subscribed to.
+ def unsubscribe_all(listener)
+ if @subscriptions
+ @subscriptions.keys.each do |event|
+ unsubscribe(event, listener)
+ end
+ end
+ end
- protected
- # Fire an event with 0 or more outbound parameters
- def fire(event, *args) #:nod
- ensure_valid event
- listeners = @subscriptions[event] if @subscriptions
- listeners.each do |l|
+ protected
+ # Fire an event with 0 or more outbound parameters
+ def fire(event, *args) #:nod
+ ensure_valid event
+ listeners = @subscriptions[event] if @subscriptions
+ listeners.each do |l|
if l.is_a? Array
l[0].send(l[1],*args)
else
- l.call(*args)
+ l.call(*args)
end
end if listeners
- end
- alias :emit :fire
- alias :notify :fire
+ end
+ alias :emit :fire
+ alias :notify :fire
- # Does nothing if the current class supports the named event.
- # Raises RuntimeError otherwise.
- def ensure_valid(event) #:nodoc:#
-# events = self.class.class_eval { @published_events }
- events = self.class.published_events
- return if events == :any_event_is_ok
- raise "Event '#{event}' not available" unless events and events.include?(event)
- end
- end
+ # Does nothing if the current class supports the named event.
+ # Raises RuntimeError otherwise.
+ def ensure_valid(event) #:nodoc:#
+ # events = self.class.class_eval { @published_events }
+ events = self.class.published_events
+ return if events == :any_event_is_ok
+ raise "Event '#{event}' not available" unless events and events.include?(event)
+ end
+ end
end
View
27 test/publisher_test.rb
@@ -92,6 +92,33 @@ def test_unsubscribe_removes_all_subscriptions_for_the_event_being_listened_for
assert_equal ['a','b','c'], out
end
+ def test_unsubscribe_all_unsubscribes_the_unsubscriber_from_all_events
+ something = Something.new
+ watcher = SomethingWatcher.new something
+
+ out = []
+ something.on :boom do
+ out << 'a'
+ end
+ something.on :boom do
+ out << 'b'
+ end
+ something.on :pow do
+ out << 'c'
+ end
+
+ something.do_boom
+ something.do_pow
+ assert_equal ['a','b','c'], out
+ assert_equal ['boom'], watcher.observations
+
+ something.unsubscribe_all self
+ something.do_boom
+ something.do_pow
+ assert_equal ['a','b','c'], out
+ assert_equal ['boom','boom'], watcher.observations
+ end
+
def test_subscribe_and_fire
obj = Something.new
Please sign in to comment.
Something went wrong with that request. Please try again.