[development] RFC: info hook standardization

Larry Garfield larry at garfieldtech.com
Mon May 19 05:15:11 UTC 2008

Unlike the IETF, I am actually looking for comments and feedback at this 
point. :-)

In recent versions, Drupal has developed an increasing number of 
registry-style hooks.  By "registry style", I mean a hook that serves to 
build a ginormous (technical term) associative array and return it, and does 
nothing else.  hook_menu(), hook_theme(), hook_node_info(), those are just a 
few of such hooks.  CCK has one for formatters and another for widgets.  
Views has hook_views_default_views() and, in Views 2, a couple of others as 
well.  There's an issue[1] to convert hook_blocks() over to that format, too, 
for a variety of reasons.

In most cases, these hooks are called rarely and then cached, either in the 
cache table or in a dedicated table such as menu_router, or they aren't but 
easily could be and probably should be.  However, it is not always readily 
apparent which is the case.  For instance, hook_forms() is not a registry 
hook in that it is contextual, and cannot be cached that way in its current 
implementation.  (Perhaps it should be, but that's not what I'm getting at.)  
Some such hooks have a corresponding _alter hook, others do not.

I therefore am going to propose a conventional standard for such 
registry-style hooks.  I will dub them "info hooks", because about half of 
such hooks currently end in _info() already.  An info hook would be defined 
as follows:

- It has a name of the form hook_$singularNoun_info().  
- It takes no parameters.
- It returns a nested associative array of arbitrary complexity 
- it has a corresponding _alter hook (vis, hook_$singularNoun_info_alter()).
- It is structured in such a way that its results can and are cached (either 
in the cache table or a dedicated table, depending on the use case).
- That cache is permanent, so under normal operation the hook never needs to 
be called again.
- The new registry system knows to never pre-load the file in which an info 
hook resides, or rather to never flag a file included for an info hook for 
pre-caching.  (We don't want to inadvertently flush the cache and then 
trigger a rebuild of those hooks on a node view page, because then we end up 
loading thousands of unnecessary lines.)

Thus, any hook that ends in _info() you can reliably know exhibits those 
properties (and possibly others), and a hook that does not end in _info() 
does not exhibit all of those properties (although it may certainly exhibit 
some of them, c.f. hook_form_alter()).

This has a number of advantages:

- Clarity.  Right now, when you see a hook you don't know inherently if it's 
cached or not, if it has an alter hook, etc.  This way, you know that if it 
ends in _info(), it either does all of the above or it's a bug.

- Consistency.  Consistent APIs are good APIs.

- Ease of development.  When developing a new hook, a developer can say to 
himself "Ah, this is starting to look like an info hook, which means I don't 
need to guess what features I should add; I should just go ahead and make a 
full info hook out of it."  You never know when that alter hook will be 
useful to someone. :-)

- Encourages declarative programming.  Eh?  Declarative programming in PHP?  
Just so!  Declarative programming is harder to make obscure, stupid bugs in 
(assuming you know the syntax), because most bugs are either syntax errors or 
blatantly obvious.  Yes there are exceptions (some of the more complex SQL 
queries I've written come to mind), but in general you're less likely to get 
subtle bugs with an associative array.

- Encourages generic engines.  A generic engine that relies on declarative 
input is flexible, because you can then program it via a declarative syntax.  
Solving the generic problem may be more difficult in the short term, but in 
the long-term it buys you a great deal of flexibility.  

- Easier to document.  Drupal's APIs are admittedly sometimes wacky and 
obscure.  By separating the engine from the declarative interface to it, we 
can put a lot of power into the hands of hook authors with a very simple, 
easy to document syntax.  We also have a clearly documented behavior for how 
an info hook is supposed to behave.  Parameter orders also then are not a 
problem, since array key orders don't matter.  The array keys also then serve 
as a form of self-documentation.

- Backward compatibility.  Yes, the unholy words!  Just like one of the 
advantages of XML is that you can arbitrarily add new tags and existing 
well-written code won't automatically choke, you can add new keys to an 
associative array and as long as there is a sane default, existing code 
doesn't have to change unless it needs to.

- Less executable code.  The key goal of the Drupal 7 code registry is to load 
less code.  Well, if we move more power into tightly written engines that are 
controlled by run-once hooks that we no longer need to load, that's less 
code, and more less code the more modules you have.  Take every module's 
hook_menu, hook_theme, hook_node_info, hook_views_default_views, hook_block, 
etc. and simply remove them from the common case.  Good bye several thousand 
lines of code.

Naturally not everything can or should be a registry hook, and we shouldn't 
try to shoe-horn Drupal into being just an array-processor.  However, this is 
a trend I have observed in Drupal development that it would behoove us to 
embrace and standardize and (dare I say!) extend the use of.  


Implementing this plan would involve documenting it, of course.  We would then 
rename hook_theme() to hook_theme_info(), hook_menu() to hook_menu_info(), 
etc.  At that point we could investigate other subsystems that it would make 
sense to turn into info hooks.  I suspect we will find a couple besides the 
block system(hook_block_info() anyone)?  In the process, we may discover 
places where "obvious" flexibility is missing.  

Excuse me while I go get my flame-retardant suit.

[1] http://drupal.org/node/257032

Larry Garfield			AIM: LOLG42
larry at garfieldtech.com		ICQ: 6817012

"If nature has made any one thing less susceptible than all others of 
exclusive property, it is the action of the thinking power called an idea, 
which an individual may exclusively possess as long as he keeps it to 
himself; but the moment it is divulged, it forces itself into the possession 
of every one, and the receiver cannot dispossess himself of it."  -- Thomas 

More information about the development mailing list