module Poro::Context::CallbackMethods

A mixin to support callbacks. There are three kinds of callbacks:

Events

Events are callbacks that are passed a handle to the object when a particular kind of event has occured. These may destructively edit objects.

Transform

Transforms are callbacks where each handler is passed the result of the previous transform, and may return any value. The issuing object then uses the final value in some way.

Filters

Calls each callback in sequence, pasing in the issuing object. Terminates execution on the first callback that is “false” (as determined by an if statement), or when there are no callbacks left. Gives the issuing object the result of the last block.

Contexts issue the following event callbacks:

:before_save

Called before save; passes the object that is going to be saved.

:after_save

Called after save; passes the object that was saved.

:before_remove

Called before removing an object from persistent storage; passes the object that will be removed.

:after_remove

Called after removing an object from persistent storage; passes the object that was removed.

:after_fech

Called after an object is fetched from the persistent store; passes the object that was fetched.

:after_convert_to_plain_object

Called after an object is converted to a plain object from the persistent store but before it is used; passes the plain object.

:after_convert_to_data

Called after an object is converted to the persistent store’s data structure but before it is used; passes the data store’s data structure.

Contexts issue the following transform callbacks:

:before_convert_to_plain_object

Called just before a context converts persistent store data to a plain ruby object; is passed the persistent store data object; the result is what is converted.

In most cases it is better to use the after_convert_to_plain_object callback event.

:before_convert_to_data

Called just before a context converts a plain ruby object to persistent store data; is passed the plain ruby object; the result is what is converted.

In most cases it is better to use the before_convert_to_plain_object callback event.

Public Instance Methods

callbacks(event) click to toggle source

Return the raw array of callbacks. This can be manipulated if more straightforward methods don’t do the trick, but usually this is a consequence of trying to solve the problem wrong.

While usually a kind of Proc, callbacks may be any object that responds to call.

# File lib/poro/context.rb, line 519
def callbacks(event)
  @event_callbacks ||= {}
  key = event.to_sym
  @event_callbacks[key] ||= []
  return @event_callbacks[key]
end
clear_callbacks(event) click to toggle source

Clear all callbacks for a given event.

This can be dangerous because

# File lib/poro/context.rb, line 534
def clear_callbacks(event)
  callbacks(event).clear
end
register_callback(event, &block) click to toggle source

Register a callback for a given event.

# File lib/poro/context.rb, line 527
def register_callback(event, &block)
  callbacks(event) << block
end

Private Instance Methods

callback_event(event, obj) click to toggle source

Fires the callbacks for the given event; returns the object supplied for calling.

  • Each registered callback is given the object issued with the call.

  • Depending on your uses, the callback may be destructive of the passed object.

  • The callback returns are ignored.

Registration of no callbacks results in no callbacks being called.

# File lib/poro/context.rb, line 548
def callback_event(event, obj)
  callbacks(event).each {|callback| callback.call(obj)}
  return obj
end
callback_filter?(event, obj, default_result=true) click to toggle source

Executes callbacks until the last true-valued filter; returns the last true valued object.

By convention, filter events should end in a question mark to make it clear that the true/false value is important.

  • Each registered callback is given the original object, making this behave more like an event than a transform.

  • Filters are expected to be non-destructive, as they are used to determine if an action should take place, rather than to take an action.

  • If the return of a callback is false-values (as determined by an if expression), then the filter chain is halted and the value is returned; otherwise, the value returned from the last callback is returned.

Registration of no callbacks results in the return of the default_value argument, which–if not provided–is set to true.

# File lib/poro/context.rb, line 585
def callback_filter?(event, obj, default_result=true)
  result = default_result
  callbacks(event).each do |callback|
    result = callback.call(obj)
    break unless result
  end
  return result
end
callback_transform(event, initial_obj) click to toggle source

Transforms an object through a callback chain; returns the transformed object.

  • Each registered callback is given the result of the previous callback.

  • Callbacks may return the original object (modified or unmodified), a copy of the original object (modified or unmodified), or an entirely new object, depending on how the result is used.

  • The callback return is passed into the next callback, with the last return being called to the initial caller.

Registration of no callbacks results in the return of the original object.

# File lib/poro/context.rb, line 564
def callback_transform(event, initial_obj)
  return callbacks(event).inject(initial_obj) {|obj, callback| callback.call(obj)}
end