Module: NoBacksies

Defined in:
lib/no_backsies.rb

Overview

NoBacksies module ecapsulates all supported callback mixins.

NoBacksies::Callbacks can be mixed-in and all supported callbacks will be applied to the class or module.

class Y
  include NoBacksies::Callbacks

  def self.list
    @list ||= []
  end

  callback :method_added do |method|
    list << method
  end

  def foo; end
  def bar; end
end

Y.list.assert #=> [:foo, :bar]

Using callbacks can easily lead to infinite loops. NoBacksies makes it easier to control callback expression via the #callback_express method.

class Z
  include NoBacksies::Callbacks

  def self.list
    @list ||= []
  end

  callback :method_added do |method|
    callback_express :method_added=>false do
      define_method("#{method}!") do
        send(method) + "!"
      end
    end
  end

  def foo; "foo"; end
  def bar; "bar"; end
end

y = Y.new
y.foo! #=> "foo!"

Calling Super

Each callback invocation passes along a superblock procedure, which can be used to invoke ‘super` for the underlying callback method. For example, it is common to call `super` in a `const_missing` callback if the dynamic constant lookup fails.

callback :const_missing do |const, &superblock|
  psuedo_constants[const] || superblock.call
end

By default, super is called after call callback procedures are called becuase that is by far the most commonly desired behavior. To suppress this behavior pass the ‘:superless=>true` flag to the `callback` method.

callback :included, :superless=>true do |mod|
  ...
end

Customizing the Underlying Callback Procedure

Every callback follows the same simply pattern, e.g. for ‘method_added`:

def self.method_added(method)
  if defined?(super)
    callback_invoke(:method_added, method){ super(method) }
  else
    callback_invoke(:method_added, method)
  end
end

So it is easy enough to customize if you have some special requirements. Say you want to call super before all callback procedures, and never allow any callback procedure to do so themselves, then you could simply redefine the underlying callback method as:

def self.method_added(method)
  super(method) if defined?(super)
  callback_invoke(:method_added, method)
end

NOTE: Currently the NoBacksies module only supports class level callbacks. We will look into adding instance level callbacks, such as ‘method_missing` in a future version.

Defined Under Namespace

Modules: CallbackMethods, Callbacks, ConstMissing, Extended, Included, Inherited, MethodAdded, MethodRemoved, MethodUndefined, SingletonMethodAdded, SingletonMethodRemoved, SingletonMethodUndefined