james mckay dot net
because there are few things that are less logical than business logic

Less is more

Okay, folks, here’s a little exercise for those of you who think that closures are a pointless, computer-science-y concept of little or no relevance to real-world programming. This is a very practical snippet of code that I had to implement this afternoon, in PHP.

You have to write a function that takes two parameters: a template string containing placeholders such as [[foo]] and [[bar]], and a hashtable containing the values that are to be substituted into the placeholders, and returns a string carrying out the substitution. Your exercise is to write such a function in as few lines as possible.

In JavaScript, you can take advantage of the fact that anonymous functions have access to the arguments passed to the function in which they are declared, to produce a very elegant solution:

function do_template(template, values) {
    return template.replace(/[[(.*?)]]/g,
        function(key) { return values[key.slice(2, -2)]; }
    );
}

In PHP, unfortunately, it is nowhere near as straightforward — while you can create functions on the fly using the create_function method, they don’t have access to the scope in which they were created, so I couldn’t use that particular trick here. The result? Twice as many lines of code to achieve the same result:

function do_template_substitute($part) {
    global $tmp_values;
    return $tmp_values[$part[1]];
}

function do_template($template, $values) {
    global $tmp_values;
    $tmp_values = $values;
    return preg_replace_callback('/[[(.*?)]]/',
        'do_template_substitute', $template);
}

Oh well, I guess PHP is a better language if you think that productivity can be measured in lines of code per day