Class Hookable::Wrapper
In: Hookable.rb
Parent: Object

Wrapper manages a number of instance methods that can easily be wrapped around instance methods of another class (as can be done with Hookable::ClassMethods#add_hook).

There are class methods to add, remove, enable or disable one or all instance methods for one target class. You can, for example, wrap one method of a Wrapper subclass around a method in Foo and, at the same time, all methods of the same Wrapper subclass around the corresponding methods in Foo.

Your wrapper method will get exactly the same arguments as the wrapped method, plus a prepended Hookable::State argument.

In your wrapper methods you can use super to run the method you’re wrapping around. See "Oddities" below.

This is probably not helpful, so here’s an example:

 require 'Hookable'

 class Something
   include Hookable

   def test_inner *args
     puts "In Something#test_inner(#{args.inspect})"
   end
   hookable :test_inner

   def test *args
     puts "In Something#test(#{args.inspect})"
     test_inner(*args)
   end
   hookable :test
 end

 class MyWrapper < Hookable::Wrapper
   def test_inner state, *args
     puts "BEGIN wrapper around test_inner"
     super
     puts "END   wrapper around test_inner"
   end

   def test state, *args
     puts "BEGIN wrapper around test"
     super
     puts "END   wrapper around test"
   end
 end

 # See 'Oddities' below!
 Kernel.send(:undef_method, :test)

 MyWrapper.add_all_to Something
 s = Something.new
 s.test(1,2,3)
 MyWrapper.disable_in Something, :test_inner
 s.test(4,5,6)
 MyWrapper.enable_all_in Something
 s.test(7,8,9)

This will produce the following output:

 BEGIN wrapper around test
 In Something#test([1, 2, 3])
 BEGIN wrapper around test_inner
 In Something#test_inner([1, 2, 3])
 END   wrapper around test_inner
 END   wrapper around test
 BEGIN wrapper around test
 In Something#test([4, 5, 6])
 In Something#test_inner([4, 5, 6])
 END   wrapper around test
 BEGIN wrapper around test
 In Something#test([7, 8, 9])
 BEGIN wrapper around test_inner
 In Something#test_inner([7, 8, 9])
 END   wrapper around test_inner
 END   wrapper around test

Oddities

There is one very important thing that might be frustrating if you happen to stumble upon it: if one if your wrappers has the same name as an instance method in Class (that includes all Kernel methods), super will not work. The error message will be very confusing, too.

Consider the code above. I have removed Kernel#test because I defined MyWrapper#test, which—as I’ve said—won’t work. If I hadn’t done that, I would have been very confused. Try it yourself if you like.

When you run into this problem, please use Hookable::State#call.

Methods

Included Modules

::Singleton

Public Class methods

Wraps all instance methods of this class around the corresponding methods of klass.

Wraps one method of this class around the corresponding method of klass.

Temporarily disables all of our wrappers in klass.

Temporarily disables one of our wrappers in klass.

Enables all of our wrappers in klass.

Enables one of our wrappers in klass.

Returns the cached Proc object for one of our wrappers.

Removes all of our wrappers from klass.

Removes one of our wrappers from klass.

[Validate]