Previous Page
Next Page

19.6. Cleverness

Don't be clever.

Tied variables are a clever idea, but "cleverness" is the natural enemy of maintainable code. Unfortunately, Perl provides endless opportunities for cleverness.

For example, imagine coming across this result selector in production code:

    $optimal_result = [$result1=>$result2]->[$result2<=$result1];

The syntactic symmetry is very elegant, of course, and devising it obviously provided the original developer with a welcome diversion from the tedium of everyday coding. But a clever line of code like that is a (recurring) nightmare to understand and to maintain, and imposes an unnecessary burden on everyone in the development and maintenance teams.

Cleverness doesn't have to be nearly that flagrant either. Having finally deduced that the example expression returns the smaller of the two results[*], you would almost certainly be tempted to immediately replace it with something like the following:

[*] The first square brackets ([$result1=>$result2]) create an anonymous array containing the two results in order. Then the second brackets index into that array. The index they use is the integer result of the less-than-or-equal-to comparison: $result2<=$result1. That comparison is true (1) if $result2 is no bigger than $result1, in which the resulting index (1) selects the second element ($result2) from the anonymous array. If $result1 is smaller than $result2, then the result of the comparison is false, which becomes zero when used as an index, which selects the first element ($result1) from the anonymous array. So the entire expression always selects whichever of the two results is smaller. Of course, it takes seven lines of careful analysis to work that out, but that's a small price to pay to enjoy High Art.

    $optimal_result = $result1 <= $result2 ? $result1 : $result2;

While that's certainly an improvement in both readability and efficiency, it still requires some careful thought to verify that it's doing the right (i.e., minimizing) thing. And everyone who maintains this code will still have to decode that expressionpossibly every time they come across it.

However, it's also possible to write that same expression in a way that's so obvious, straightforward, and plain-spoken that it requires no effort at all to verify that it implements the desired behaviour:

    use List::Util qw( min );

    $optimal_result = min($result1, $result2);

It's not "clever" and it's even marginally slower, but it is clean, clear, efficient, scalable, and easy to maintain. And that's always a much better choice.

    Previous Page
    Next Page