whateverthing.com

Coding by the Campfire

People sometimes talk about the Campsite Principle of coding, of taking the time to make things better for the person coming after you.

Well, I was recently doing some programming at an actual campsite, and let me tell you: there's only so much you can clean up as your battery winds down to zero.

Programming while camping probably isn't the greatest idea, since there are other things to do and kids that need to be supervised. But when everything is wrapped up, the kids are asleep, and it's just you by the campfire ... it can be pretty magical.

Unless, as happened to me, your laptop is down to 25% battery and you don't have a way to charge it. I'd spent the majority of the battery power processing photos from a hike earlier that day.

So, with the power slipping away, I decided that the best I could do was isolate a tiny chunk of my hobby codebase and tidy it up.

I settled on a function I wrote many years ago called "getIfNotEmpty". This was a helper to fetch a key from an array without triggering a PHP warning if the key didn't exist.

function getIfNotEmpty($array, $key, $defaultValue = null)
{
    return isset($array[$key]) ? $array[$key] : $defaultValue;
}

// usage example:
$userAgent = getIfNotEmpty($_SERVER, 'HTTP_USER_AGENT');

It was fairly simple, but more importantly, in PHP 7.x it was obviated by the Null Coalesce Operator. This meant that I could factor it out of the codebase entirely, and I only had to change about 15 invocation locations.

The Null Coalesce operator is great for this problem. Historically in PHP, code that peeked into arrays like this had to be wrapped in all kinds of malarkey like the above. This helped to prevent notices and warnings stemming from non-existent array keys. Now, with a simple "??", you can specify a default value and move on.

$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';

While I was replacing the invocations, I noticed some areas where I had specified a default of "null", despite clearly using the resulting value in a string. In the interests of consistency, that should've been an empty string, so I fixed those cases as well.

In another place, I had a compound concatenation scenario (attaching two results with a hyphen). This got me into a bit of hot water that, thankfully, my phpunit tests were able to point out.

$site = getIfNotEmpty($_SERVER, 'SERVER_NAME', '')
      . ' - '
      . getIfNotEmpty($_SERVER, 'SERVER_ADDR', '');

It turned out that in order for the concatenation operations to work correctly, I had to wrap the null coalesce operation in parentheses.

$site = ($_SERVER['SERVER_NAME'] ?? '')
      . ' - '
      . ($_SERVER['SERVER_ADDR'] ?? '');

(I'm actually having a hard time replicating the exact conditions that required the parenthesis for this example, so these might technically be unnecessary.)

The parenthesis aren't always required, but they can be quite useful for making the order of operations easier to read:

// confused in-between state
$ip = $remote_addr ?: $_SERVER['REMOTE_ADDR'] ?? '';

// fixed
$ip = $remote_addr ?: ($_SERVER['REMOTE_ADDR'] ?? '');

By the time all of this was done and committed, and the phpunit tests had confirmed nothing obvious was broken, I was down to 10% battery.

Time for bed.

Now I could sleep tight, knowing that my codebase was the tiniest bit cleaner thanks to applying the Campsite Principle at an actual campsite.


Oh, before I forget - another magical thing about camping: Smoreos!

Published: August 28, 2018

Categories: coding

Tags: coding, dev, development, legacy, php, maintenance, fun