Observers
Observe objects of any kind and trigger actions/events on them.
Observers are decoupled from the objects they observe. Instead of directly observing a particular object, we observe the "key" that represents that object. Anything can be observed out of the box; a class, an object, a struct, symbol or string. You just need to observe it:
class MySubscriber
include Observers
observe MyPublisher
def self.handle
# Method that will be called upon trigger.
end
endYou can also add observers from the object being observed:
class MyPublisher
include Observers
observers << MySubscriber
endℹ️ Note: Observers are called in the order that they are defined.
Triggers
include Observers in the class that you'd like to trigger actions/events from:
class MyPublisher
include Observers
# "trigger" method now available on class and instance.
endActions
Calls the my_action method on MySubscriber and returns the last observer's return value that was non-nil:
MyPublisher.trigger action: :my_actionTrigger the action on any observers to any_object_or_class:
MyPublisher.trigger any_object_or_class, action: :my_actionEvents
Observers integrates with LowEvent, allowing you to pass an event to your observer.
Calls the handle(event:) method on all observers to MySubscriber and return the last observer's return value that was non-nil:
MyPublisher.trigger event: LowEvent.new(event_data)Trigger the event on any observers to any_object_or_class:
MyPublisher.trigger any_object_or_class, event: LowEvent.new(event_data)ℹ️ Note: Events should inherit from LowEvent or replicate its methods and attributes.
Default Action
The default action that will be called on an observer is handle or handle(event:) if the action, event or action don't specify this.
Overriding Actions
An action can be overridden at each layer:
- On the
triggermethod by including anaction:keyword argument - On the event by populating its
actionattribute - On the observer by configuring an
action:onobserve:
class MySubscriber
include Observers
observe MyPublisher, action: :clear_cache
def self.clear_cache
# The `clear_cache` method will be called regardless of the trigger's action/event's action.
end
endAction Precedence
-
observe action:andobservers << my_object, action:- Overridestriggerand event actions -
trigger action:- Overrides event actions - Event's
@action- Overrides Observers' default action
API
Observers
The observers method is more flexible than it seems.
Reference an object other than self to observe:
observers(my_object) << my_observerOverride the action called on the observer with:
observers.push(my_observer, action: :overridden_action)ℹ️ Note: push needs to be used instead of << in this situation so that Ruby doesn't get confused about the syntax.
Actions
-
trigger- Calls all observers. Returns the last non-nil value. -
take- Calls all observers up until the first non-nil value. Returns the first non-nil value.
Installation
Add gem 'observers' to your Gemfile then:
bundle install