fromMarch 2013
Column:

Drupl'Art

Sculting Conditionals
0

At DrupalCon Paris, I attended a grid presentation by Mark Boulton, for designers. I didn’t get it. Recently I read the biography of Steve Jobs. Now I get it. Drupal designers like Mark focus on the art outside. For several issues, this column has focused on the art inside. At the risk of redundancy, let me state that when I talk about Drupl'Art I am talking mostly about the art within.

Aesthetic Minimalist

Like all artists, I navigate my craft through stylistic seas. Most recently, I sailed into an Extreme Minimalist Period: fewer lines of code mattered to me. Eventually, Charlie (chx) politely suggested that, if I insisted on charting that course, to at least comment it better. He was right, I was wrong; and I offer up a heart-felt mea culpa to the developers who followed in my turbulent wake and are now stuck with the flotsam and jetsam.

I am still a Minimalist, but now an aesthetically practical Minimalist; readability and maintainability carry the day. Farewell to saving opcodes!

Picasso, Van Gogh, Renoir, Monet, Klimt — even Romero Britto — all have a unique style that is instantly recognizable. Brushstrokes, shapes, colors, and raw materials are part of what makes their work distinctive. While I like the metaphor of paintings, mostly because I am a fan of this medium, what we do as software writers is more akin to clay sculpting — take away a little here, add something there, move this around bit...

So let's talk about software sculpting.

In this installment of Drupl’art, I review specific Drupal PHP examples; from common mistakes, to merely-acceptable design patterns, to those I consider superior — Drupal brushstrokes, Drupal sculpting.

Let's start with the assignment-conditional:

if ($foo = bar()) {
}

That is too minimalistic. While it’s valid PHP, it is prone to error. As a code reviewer, I wonder if the author intended a conditional check rather than the assignment (== instead of =). A comment could clarify this:

if ($foo = /* not == */ bar()) {
}

But this is still unpleasing to me. It is cleaner to just use two lines of code:

$foo = bar();
if ($foo) {
}

Next, ask if $foo is ever used; if not, just eliminate it:

if (bar()) {
}

Good. Now let's consider a more complex conditional:

if ($something || $foo = bar()) {
}

This brings up the question of precedence. If $something is TRUE then the second half of the conditional is not evaluated. You might think, “Hey, let's just switch the ordering.” But be careful here, because there's another precedence pitfall. If you merely rearrange it as below, then $foo is set to "bar() || $something." That’s wrong:

if ($foo = bar() || $something) {
}

In this case, we need to use parentheses to force precedence:

if (($foo = bar()) != 0 || $something) {
}

While this is now technically correct, it's a bit hard to read. Let’s break the conditional assignment onto another line.

$foo = bar();
if ($foo || $something) {
}

An interesting PHP style I've come to like is the !assignment-comparison; it is compact and non-ambiguous.

if (!($foo = bar())) {
}

If used in a simple comparison, the extra parentheses in PHP are not necessary. Instead:

if (!$foo = bar()) {
}

Let’s look at more conditionals:

if ($something) {
  return $first;
}
else {
  return $second;
}

First question: is the variable $something possibly not set? If so, we must use:

if (!empty($something)) {
  return $first;
}
else {
  return $second;
}

I dislike negative logic. If PHP had a function called notempty() to compliment the empty() function, then we would use it here, but since PHP does not, I would drop the NOT operator and swap the clauses.

if (empty($something)) {
  return $second;
}
else {
  return $first;
}

This can be written still more compactly and remain just as readable:

if (empty($something)) {
  return $second;
}
return $first;

Even simpler:

return empty($something) ? $second : $first;

Sculpting

Thomas Edison is credited as saying "Genius is one per cent inspiration, ninety-nine per cent perspiration." Most great achievement comes through hard work. Write your code, get it to work, and play with it like a sculptor plays with clay.

You'll know when it's right.