Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

unsubscribe_all method, a nice alias, and whitespace fixes #1

Merged
merged 3 commits into from

2 participants

@ttencate

Thanks for this shiny little gem! Here are some improvements that I needed, hope you like 'em :)

@shawn42 shawn42 merged commit 84abc31 into atomicobject:master
@shawn42
Owner

Thanks @ttencate I like the jquery style of the off method. I've also monkey patched unsubscribe_all many-a-times. Great contributions.

@ttencate

Yes, that was indeed inspired by jQuery. If we're going to have 'on', we might as well have 'off' as well :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
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
Something went wrong with that request. Please try again.