Skip to content

Instantly share code, notes, and snippets.

@buren
Last active January 23, 2018 16:23
Show Gist options
  • Save buren/9f754d64588d0d08685c968cca9a10bd to your computer and use it in GitHub Desktop.
Save buren/9f754d64588d0d08685c968cca9a10bd to your computer and use it in GitHub Desktop.
Simple event emitter
# Returns an event emitter class with given event names
# @return [Object] the event emitter class
# @param [String, Symbol] event_names
# @example Simple event emitter
# class CrawlEvent < EventEmitter(:found_url, :page_title)
# end
#
# event = CrawlEvent.new do |on|
# on.every_found_url { {|url| puts "Found URL: #{url}" }
# on.every_page_title { {|title| puts "Page title: #{title}" }
# # you can add multiple blocks
# on.every_page_title { |title| puts "[WARNING] Title too long!: #{title}" if title.length > 155 }
# end
#
# event.emit_page_title(page_title)
# event.emmit_found_url(url)
def self.EventEmitter(*event_names)
Class.new do
def initialize
yield(self) if block_given?
end
event_names.each do |name|
define_method("emit_#{name}") do |*args|
blocks_for(name).each { |block| block.call(*args) }
end
define_method("every_#{name}") do |*args, &block|
raise(ArgumentError, 'block must be given!') unless block
blocks_for(name) << block
end
define_method(:blocks_for) do |name|
variable_name = "@#{name}_blocks"
if value = instance_variable_get(variable_name)
value
else
instance_variable_set(variable_name, [])
end
end
end
end
end
require "spec_helper"
require "event_emitter"
RSpec.describe EventEmitter(:data_point) do
describe "#initialize" do
it "yields self to block" do
event = nil
event_handler = described_class.new do |handler|
event = handler
end
expect(event).to eq(event_handler)
end
end
describe "#data_point event" do
it "can register and emit event" do
result = nil
handler = described_class.new do |on|
on.every_data_point { |data| result = data }
end
data = 2
handler.emit_data_point(data)
expect(result).to eq(data)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment