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