Posts Tagged hooks

Hooks goes without ActiveSupport and still has inheritable attributes

Sunday, October 3rd, 2010

The ongoing discussions about ActiveSupport in Hooks lead me to believe that ActiveSupport is not as popular as i thought it is.

Don’t get me wrong, I didn’t get misleaded by comments like

ActiveSupport sucks and monkey craps on too many classes

although some of this is true :-D It has wonderful helper methods and there’s a lot of work done for you already, but ActiveSupport is simply too complex.

After I found out that Class.class_inheritable_array fails when doing

require "activesupport/core_ext/class/inheritable_attributes"

with some undefined method exception (at least with 2.3.9), I finally decided to do it on my own.

Hooks::InheritableAttribute

The current implementation is simple.

You use it like

class Cat
  extend Hooks::InheritableAttribute
  inheritable_attr :lifes
  self.lifes = []

and in subclasses

class Garfield < Cat
  self.lifes << "second"

so it is like ActiveSupport’s class_inheritable_array. Less code, of course.

Where to go?

Not sure if methods like that should be packaged in separate gems? Or in a more generic gem aggregating features?

I mean, it would end up in some big PassiveLaziness gem and we’d have two mainlines of handy ruby feature libraries.

So where to put such code? How can we make it modular and easily useable without automatically monkey patching every second class, as ActiveSupport does?

Any thoughts welcome!

Hooks and callbacks for Ruby. But simple.

Friday, September 24th, 2010

Callbacks are executable things, like a Proc or methods in Ruby, whereas a hook is usually a spot in your code where you want to execute a certain subset of callbacks.

Or, precisely, callbacks that are associated to the hook.

I have lots of these places throughout my libraries, and after playing around with ActiveSupport::Callbacks (both 2.3 and 3.0) I wrote a minimal gem to do exactly that:

Declaratively define hooks, add callbacks and run them with the options you like.

Let’s see how it works. First, install hooks.

$ gem install hooks

Using hooks

Usually you’d define hooks declaratively in your class.

class Coder
  include Hooks
 
  define_hook :after_work

You’re now ready to add callbacks, as your class now has a Class.after_work method. Nothing more.

class Coder
  after_work do
    puts "Yeah!"
  end

Instance methods are also callback’able.

  after_work :have_a_beer
 
  def have_a_beer
    puts "One for me, one for MichaƂ!"
  end

Now, run a hook somewhere in your code.

  def finish
    cleanup!
    run_hook :after_work
  end

The callbacks will be invoked in the order you added them. Sweet.

Running a hook with arguments

If you need objects in your callbacks, just pass ‘em.

    run_hook :at_work, self, Time.now

And be sure to equip your callbacks with the right parameters.

  at_work do |who, when| ... end

Filters?

So, basically a filter as found in Rails controllers is a hook. You – the user – use Controller.after_login to add callbacks. And somewhere in the Rails core, there’d be a call to

  run_hook :after_login, self

…if they’d be using hooks.