Basic Example¶ ↑
First require the NoBacksies
library.
require 'no_backsies'
Include the Callbacks module in a class and define a callback procedure.
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
We can see that list
holds the methods added.
Y.list.assert == [:foo, :bar]
Callback Expression¶ ↑
NoBacksies
makes it easier to control callback expression. This is useful in the prevention of infinite recursion. For instance, infinite recursion is a common problem when a method_added
callback defines a new method.
Here is an example that demonstrates how to work around this problem using the callback_express
method.
class Z include NoBacksies::Callbacks 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
In this example, a new ‘Z` object will get an automatically defined bang method for every explicitly defined method.
z = Z.new z.foo #=> "foo" z.foo! #=> "foo!" z.bar #=> "bar" z.bar! #=> "bar!"
Callback Options¶ ↑
Once Callback Option¶ ↑
NoBacksies
supports special callback options. The first is :once
. By setting :once
to true
, the callback will be used one time and then removed.
class Q include NoBacksies::Callbacks def self.list @list ||= [] end callback :method_added, :once=>true do |method| list << method end def foo; "foo"; end def bar; "bar"; end end
Here we see that only :foo has been added to the list.
Q.list #=> [:foo]
Safe Callback Option¶ ↑
The other option supported is :safe
. When :safe
is set to true the callback is automatically wrapped in an callback_express block that sets the expression of the callback to false while it is being processed. This means we can rewrite our first example more succinctly.
class Z2 include NoBacksies::Callbacks callback :method_added, :safe=>true do |method| define_method("#{method}!") do send(method) + "!" end end def foo; "foo"; end def bar; "bar"; end end
In this example, a new ‘Z` object will get an automatically defined bang method for every explicitly defined method.
z = Z2.new z.foo #=> "foo" z.foo! #=> "foo!" z.bar #=> "bar" z.bar! #=> "bar!"
Method Added¶ ↑
Given a class that defines a no-backsies method_added
callback.
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
Then the results are as follows.
Y.list #=> [:foo, :bar]
Method Removed¶ ↑
Given a class that defines a no-backsies method_removed
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :method_removed do |method| list << method end def foo; end def bar; end remove_method(:foo) remove_method(:bar) end
Then the results are as follows.
Y.list #=> [:foo, :bar]
Method Undefined¶ ↑
Given a class that defines a no-backsies method_undefined
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :method_undefined do |method| list << method end def foo; end def bar; end undef_method(:foo) undef_method(:bar) end
Then the results are as follows.
Y.list #=> [:foo, :bar]
Singleton Method Added¶ ↑
Given a class that defines a no-backsies singleton_method_added
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :singleton_method_added do |method| list << method end def self.foo; end def self.bar; end end
Then the results are as follows.
Y.list #=> [:foo, :bar]
Singleton Method Removed¶ ↑
Given a class that defines a no-backsies singleton_method_removed
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :singleton_method_removed do |method| list << method end def self.foo; end def self.bar; end class << self remove_method(:foo) remove_method(:bar) end end
Then the results are as follows.
Y.list #=> [:foo, :bar]
Singleton Method Undefined¶ ↑
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :singleton_method_undefined do |method| list << method end def self.foo; end def self.bar; end class << self undef_method(:foo) undef_method(:bar) end end Y.list #=> [:foo, :bar]
Constant Missing¶ ↑
Given a class that defines a no-backsies const_missing
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :const_missing, :superless=>true do |const| list << const end FOO BAR end
Then the results are as follows.
Y.list #=> [:FOO, :BAR]
Notice we used ‘:superless` to prevent super from being called, which would have raised an NameError.
Included¶ ↑
Given a class that defines a no-backsies included
callback.
module U include NoBacksies::Callbacks def self.list @list ||= [] end callback :included do |mod| list << mod end end class X include U end class Y include U end
Then the results are as follows.
U.list #=> [X, Y]
Extended¶ ↑
Given a class that defines a no-backsies extended
callback.
module U include NoBacksies::Callbacks def self.list @list ||= [] end callback :extended do |mod| list << mod end end class X extend U end class Y extend U end
Then the results are as follows.
U.list #=> [X, Y]
Inherited¶ ↑
Given a class that defines a no-backsies inherited
callback.
class Y include NoBacksies::Callbacks def self.list @list ||= [] end callback :inherited do |base| list << base end end z = Class.new(Y)
Then the results are as follows.
Y.list #=> [z]