The unset($args[0]) PHP Pattern

Suppose you are working on a system, and want to allow users to use so-called hooks to hook into the system and change it’s behavior. Think of it as wordpress’ filter/action kind-of-thing. This is in a way, something similar to events in javascript, and the purpose is basically the same: you want to do, or let others do something when something else happens, and potentially change the way the system works, or extend its functionality.

Implementing this kind of feature is surprisingly simple. All you need is a way to let people subscribe to your hooks, and a way to call all subscribed members for a certain hook at some point. The implementation details are not really our concern right now, but what happens when you call each subscribed member.

In order for hooks to be useful, you need to be able to pass relevant information to the subscribed members at call time. For example, in Javascript, native events get passed an event object that contains all sorts of useful information. The way you pass this information to the subscribed members will depend on your implementation of the subscribe method you use.

One pattern I’ve noticed working with drupal is unset($args[0]).

Drupal uses a hook system that allows developers to hook into the system simply by following some function naming conventions. The drupal specifics are not important right now. What is important is the way drupal calls its hooks: it uses a function called module_invoke_all.

The module_invoke_all function, in its definition, takes a single argument: the name of the hook. We already mentioned the importance that being able to pass information to the subscribed member has, so why is it that the drupal function to invoke hooks takes only the name of the hook as argument? How do you pass the relevant information?

PHP, just like other programming languages allows you to pass more arguments to a function that its formal parameters. The way you access the extra arguments passed to the function varies depending on the language. In php all arguments passed to a function are kept in the $args array.

Lets say you call module_invoke_all as follows:

module_invoke_all(‘my_hook’, ‘something cool’, ‘something interesting’);

Inside the function, the $args array will have 3 members, one for each argument passed to it. So, if you want to pass those values, minus the hook name to the subscribed members, all you need to do is get rid of that, and pass the resulting array to the subscribed members. That is why unset($args[0]) does.

I’m not sure this is the best way to do it, but it is certainly interesting. If you want to read the full code for the module_invoke_all function, just check out the drupal documentation on it (https://api.drupal.org/api/drupal/includes!module.inc/function/module_invoke_all/7)

Infinite Function Calls: Javascript

I was about to sleep last night, when a nice pattern came to my mind. I had already played with something similar in the past, but not to the level that I’m playing now. I call it the Infinite Function Calls Pattern. I am unaware if anyone has come up with this pattern before. All I know is I have never seen it before.

A function in Javascript can return anything, even another function. So you can do this:


var a = function(){
    alert('Hello');
    return function(){
        alert('World');
    }
}

If you follow this blog regularly, you should already be familiar with that pattern. What you may or may not know is that you can execute the returned function right away:

a()();

Pretty Cool! This kind of thing can be really useful in certain situations. However, you can only chain as many immediate calls as returned functions. This is where the new pattern improves this one.

Lets see an example:


var a = function(n){
    n++;
    alert(n);
    a = function(){
        n+=n;
        alert(n);
        return a;
    }
    return a;
}

a(1)()()()()()()()()()()();

You can basically add as many immediate calls as you want. I still haven’t come up with a real-life situation where we could use this pattern, but it is nice to know that it exists. Lets see another interesting example:


var a = function(n){
    n++;
    alert(n);
    a = function(m){
        m = m || n;
        n+=m;
        alert(n);
        return a;
    }
    return a;
}

a(1)()(6)()()()()(23);

Here we are passing parameters to the function and it reacts differently than in the previous example. Based on this, we could create something like this to generate markup:


var p = function(content){
    var _p = document.createElement('p');
    var _t = document.createTextNode(content);
    _p.appendChild(_t);
    document.body.appendChild(_p);
    
    return p;
}

p('Hello')('World')('My Name Is')('My Name Is')('Slim Shaddy');

As you can see, here we don’t even need to redefine the function like in our previous examples. As long as the function returns itself we can call it infinitely:


var a = function(n){
    alert(n);
    return a;
}

a(1)(2)(3)(4)(5);

The reason we were redefining the function before was to create a closure over n so that we could re-use it as many times as we wanted. That is a really powerful way of using this pattern, but we will come back to that later on another post. For now, lets expand our markup generating function a bit more:


var mk = function(content,tag){
    tag = tag || 'p';
    var el = document.createElement(tag);
    var cont = document.createTextNode(content);
    el.appendChild(cont);
    document.body.appendChild(el);
    
    return mk;
}

mk('Hello','div')('World', 'i')('My Name Is', 'strong')('My Name Is')('Slim Shaddy');

I changed the function name and the internal variables, but most of the function is still the same. However, we can now specify what kind of element we want to generate. There is a lot of room for improvement on this function, for example, you could specify what element you want the generated markup to be appended to.

This pattern could be used for many more other tasks, like lazy recursion, or data evaluation. If you are feeling particularly masochist, you could even use eval to generate a different amount of function calls on the fly:


var mk = function(content,tag){
    tag = tag || 'p';
    var el = document.createElement(tag);
    var cont = document.createTextNode(content);
    el.appendChild(cont);
    document.body.appendChild(el);
    
    return mk;
}

var calls = 500,
    cont = 'foo',
    exec = 'mk';
    
for(var i = 0; i < calls; i++){
    exec += '("' + cont + '")';
}

eval(exec);

Although, I don’t recommend this.

As you can see, this is a very interesting pattern that allows for many interesting things to be made. If you come up with some great ideas of where this could be useful, let us know via the comments form.