lib/emittance/event.rb in emittance-0.0.2 vs lib/emittance/event.rb in emittance-0.0.3
- old
+ new
@@ -24,50 +24,121 @@
# def validate_payload
# raise Emittance::InvalidPayloadError unless payload.is_a?(String)
# end
# end
#
- # == Custom Identifiers
+ # == Identifiers
#
+ # Events are identified by what we call "Identifiers." These come in the form of symbols, and can be used to identify
+ # specific event types.
+ #
+ # === Identifier Naming
+ #
+ # The naming convention for events and their identifiers goes like this: the name of an event class will be the
+ # CamelCase form of its identifier, plus the word +Event+. For example, +FooEvent+ can be identified with +:foo+.
+ # Thus, the events received by watchers of +:foo+ will be instances of `FooEvent`. Conversely, if you make an event
+ # class +BarEvent+ that inherits from +Emittance::Event+, its built-in identifier will be +:bar+. You can see what
+ # a +Emittance::Event+ subclass's identifier is by calling +.identifiers+ on it.
+ #
+ # class SomethingHappenedEvent < Emittance::Event
+ # end
+ #
+ # MyEvent.identifiers
+ # # => [:something_happened]
+ #
+ # MyEvent.new.identifiers
+ # # => [:something_happened]
+ #
+ # The namespace resultion operator (+::+) in an event's class name will translate to a +/+ in the identifier name:
+ #
+ # class Foo::BarEvent < Emittance::Event
+ # end
+ #
+ # Foo::BarEvent.identifiers
+ # #=> [:'foo/bar']
+ #
+ # === Custom Identifiers
+ #
# By default, the identifier for this event will be the snake_case form of the class name with +Event+ chopped off:
#
- # FooEvent.identifier # => :foo
+ # FooEvent.identifiers
+ # # => [:foo]
#
# You can set a custom identifier for the event class like so:
#
# FooEvent.add_identifier :bar
+ # FooEvent.identifiers
+ # # => [:foo, :bar]
#
- # Now, when emitters emit +:bar+, this will be the event received by watchers.
+ # Now, when emitters emit +:bar+, this will be the event received by watchers. +#add_identifier+ will raise an
+ # {Emittance::IdentifierCollisionError} if you attempt to add an identifier that has already been claimed. This
+ # error will also be raised if you try to add an identifier that already has an associated class. For example:
#
+ # class FooEvent < Emittance::Event
+ # end
+ #
+ # class BarEvent < Emittance::Event
+ # end
+ #
+ # BarEvent.add_identifier :foo
+ # # => Emittance::IdentifierCollisionError
+ #
+ # This error is raised because, even though we haven't explicitly add the identifier +:foo+ for +FooEvent+, Emittance
+ # is smart enough to know that there exists a class whose name resolves to +:foo+.
+ #
+ # It's best to use custom identifiers very sparingly. One reason for this can be illustrated like so:
+ #
+ # class FooEvent < Emittance::Event
+ # end
+ #
+ # FooEvent.add_identifier :bar
+ # FooEvent.identifiers
+ # # => [:foo, :bar]
+ #
+ # class BarEvent < Emittance::Event
+ # end
+ #
+ # BarEvent.identifiers
+ # # => []
+ #
+ # Since +BarEvent+'s default identifier was already reserved when it was created, it could not claim that identifier.
+ # We can manually add an identifier post-hoc, but this would nevertheless become confusing.
+ #
class Event
class << self
- # @return [Symbol] the identifier that can be used by the {Emittance::Broker broker} to find event handlers
- def identifier
- EventBuilder.klass_to_identifier self
+ # @return [Array<Symbol>] the identifier that can be used by the {Emittance::Broker broker} to find event handlers
+ def identifiers
+ EventLookup.identifiers_for_klass(self).to_a
end
# Gives the Event object a custom identifier.
#
# @param sym [Symbol] the identifier you wish to identify this event by when emitting and watching for it
def add_identifier(sym)
- EventBuilder.register_custom_identifier self, sym
+ raise Emittance::InvalidIdentifierError, 'Identifiers must respond to #to_sym' unless sym.respond_to?(:to_sym)
+ EventLookup.register_identifier self, sym.to_sym
end
- # @private
+ # @param identifiers [*] anything that can be derived into an identifier (or the event class itself) for the
+ # purposes of looking up an event class.
def event_klass_for(*identifiers)
- EventBuilder.objects_to_klass *identifiers
+ EventLookup.find_event_klass(*identifiers)
end
end
attr_reader :emitter, :timestamp, :payload
+ # @param emitter the object that emitted the event
+ # @param timestamp [Time] the time at which the event occurred
+ # @param payload any useful data that might be of use to event watchers
def initialize(emitter, timestamp, payload)
@emitter = emitter
@timestamp = timestamp
@payload = payload
end
- def identifier
- self.class.identifier
+ # @return [Array<Symbol>] all identifiers that can be used to identify the event
+ def identifiers
+ self.class.identifiers
end
end
end