Module Core::Patterns::Observable
In: core/patterns.rb

Implementation of the Observable pattern. Classes including this module will be able to signal events. This event will be notified to the list of registered observers for this class. This is an example on how to use this pattern:

 class Controller
   include Observable
   add_event :before_load, :after_load

   def load
     signal_event :before_load
     print 'Loding... '
     sleep 2
     puts 'done.'
     signal_event :after_load
   end
 end

 class Service
   include Observer
 end

 c = Controller.new
 c.add_observer :before_load, Service.new  # -> Registered observers:
                                           # -> {:before_load=>[<Service:0x24aa4>]}

 c.add_observer :after_load, Service.new   # -> Registered observers:
                                           # -> {:before_load=>[<Service:0x24aa4>], :after_load=>[<Service:0x247d4>]}

 c.load                                    # -> Service (<Service:0x24aa4>) notified of :before_load
                                           # -> Loding... done.
                                           # -> Service (<Service:0x247d4>) notified of :after_load

Methods

Classes and Modules

Module Core::Patterns::Observable::ClassMethods

Public Instance methods

Observers of any object are registered using this instance method. The obj must include the Observer module. A symbol for one of the events registered for this class (See ClassMethods#add_event and ClassMethods#get_events) should be provided in event.

[Source]

# File core/patterns.rb, line 82
      def add_observer(event, obj)
        # check that the event +obj+ is trying to subscribe is provided by this class.
        if not self.class.get_events.include?(event)
          raise NameError.new(
            "The event :#{event} is not recognized by the class #{self.class.name}. " +
            "Use #{self.class.name}.get_events() to get a list of valid events for the class."
            )
        end

        # initialize this object's instance variables if this has not been done 
        # before
        @observers = {} if not defined? @observers
        @observers[event] = [] if not @observers.key?(event)

        # register the subscriber for the +event+
        if @observers[event].include?(obj)
          # TODO: show a warning, the observer was previously added to this event
          puts "Warning, #{obj.inspect} is already and observer for :#{event} in this object."
        else
          @observers[event] << obj 
        end

        puts "Registered observers:\n\t#{@observers.inspect}"
      end

Get the list of current Observers of this instance. If no event is provided, the full hash of Observers of this object is returned.

[Source]

# File core/patterns.rb, line 109
      def get_observers(event=nil)
        @observers = {} if not defined? @observers
        event.nil? ? @observers : @observers.fetch(event, nil)
      end

Protected Instance methods

This method is used by objects that are instances of classes that implement the Observable pattern to notify to the different Observers registered that an event has just occured.

  • event the symbol that represents the event being signaled. See ClassMethods#add_event for details.
  • args a list of parameters associated with the event. The default implementation prepends the a reference of the object signaling the event so the Observers can identify it.

[Source]

# File core/patterns.rb, line 124
      def signal_event(event, *args)
        @observers = {} if not defined? @observers
        @observers.fetch(event, []).each do |observer|
          args.unshift(self)
          observer.notify event, *args
        end
        return nil
      end

[Validate]