Skip to content

Instantly share code, notes, and snippets.

@davybrion
Created September 15, 2012 14:24
Show Gist options
  • Save davybrion/3728187 to your computer and use it in GitHub Desktop.
Save davybrion/3728187 to your computer and use it in GitHub Desktop.
code snippets for "Using More Rubyesq Events In Ruby" post
class Something
include EventPublisher
event :some_event
end
something.subscribe :some_event, method(:some_handler)
something.subscribe(:some_event) { |args| puts "something happened!" }
something.unsubscribe :some_event, method(:some_handler)
class Event
attr_reader :name
def initialize(name)
@name = name
@handlers = []
end
def add(method=nil, &block)
@handlers << method if method
@handlers << block if block
end
def remove(method)
@handlers.delete method
end
def trigger(*args)
@handlers.each { |handler| handler.call *args }
end
end
module EventPublisher
def subscribe(symbol, method=nil, &block)
event = send(symbol)
event.add method if method
event.add block if block
end
def unsubscribe(symbol, method)
event = send(symbol)
event.remove method
end
private
def trigger(symbol, *args)
event = send(symbol)
event.trigger *args
end
self.class.class_eval do
def event(symbol)
getter = symbol
variable = :"@#{symbol}"
define_method getter do
event = instance_variable_get variable
if event == nil
event = Event.new(symbol.to_s)
instance_variable_set variable, event
end
event
end
end
end
end
class Publisher
include EventPublisher
event :notify
def trigger_notify
trigger :notify, "hello world!"
end
end
class SubscriberWithMethod
def start_listening_to(publisher)
@publisher = publisher
@publisher.subscribe :notify, method(:notify_handler)
end
def stop_listening
@publisher.unsubscribe :notify, method(:notify_handler)
end
def notify_handler(args)
puts "#{self.class.to_s} received: #{args}"
end
end
class SubscriberWithBlock
def start_listening_to(publisher)
@publisher = publisher
@publisher.subscribe(:notify) { |args| puts "block received: #{args}" }
end
end
publisher = Publisher.new
subscriber1 = SubscriberWithMethod.new
subscriber2 = SubscriberWithBlock.new
subscriber1.start_listening_to publisher
subscriber2.start_listening_to publisher
publisher.trigger_notify
subscriber1.stop_listening
publisher.trigger_notify
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment