Legend of the Whale

As has become tradition, every year I design and run a one-shot Dungeons & Dragons game for my co-workers at our annual gathering. This year I was heavily inspired by my experiences playing Breath of the Wild and I wanted to try to re-create that particular “Zelda” feeling in D&D. I’d love to have done more but there’s only so many puzzles you can fit into a 3 hour game!

The adventure is a one-shot adventure for a group of 2nd-level characters and runs in just about 3 hours. It was designed to be fun for brand new players and experienced gamers alike. Myself and several wonderful volunteer DMs ran the game seven times over the past few weeks and I think it runs pretty smooth.

Here is the teaser text:

One hundred years ago the realm of Dunelin built four magical monuments in the shapes of giant animals to concentrate their power and defend against a demon’s attack. Sadly, they did not account for the cunning of their adversary. The demon took control of the monuments, turning them against their creators, making him nearly unstoppable.

Though it cost her life, the realm’s most powerful wizard was able to bind the demon in a magic circle, buying her people some time. All of the demon’s rage is now focused against his prison, and after a hundred years he is close to breaking free.

Time to to recover the monuments is running out.

You may download the adventure yourself here: http://bit.ly/legend-of-the-whale

Photo by Roberto Lopez on Unsplash

Safely coding with constants

In PHP there is a tendency to assume that the code we are working on is the only code that is running. The global and transactional nature of the language’s past has made this easy to do.

This tendency naturally leads us to use global state, and while there does seem to be a resistance to using global variables, I’ve only seen increased usage of constants created using define(). I would like to suggest that constants created in this way are actually just global variables by another name. Worse, perhaps, they are global variables whose values cannot be changed during runtime. If that last bit seems like an advantage rather than a disadvantage, read on.

First let’s briefly cover the risk of global state. As I’ve seen in my experience over and over again, the nature of code is to proliferate over time and when code starts to have complexity, global state becomes a liability. Anything the programmer cannot see directly when coding is something they have to keep in their head. And there is only so much we can keep in our heads, especially when large periods of time pass and when many different people are involved. A local variable (local state) is much easier to reason about, because it’s “right there” in front of us and less likely to be affected by things “somewhere else”.

There’s more to it than just making code more readable, though. Another way we learn about and protect code from bugs is by testing, both automated and manual. The nature of testing is to try some code, then change the state and try it again to see what the effects are. Remember how I said that constants created by define() cannot change? Let’s look at an example,

function getGroceries(): string {
  if (defined('LIKES_PEAS')) {
    return purchasePeas();
  }
  return purchaseCarrots();
}
// ...
echo "I will buy some " . getGroceries();

How would we write a test case for this function? The risk of having a condition on a defined constant is that apart from manual testing it is impossible to test it. Constants by their very nature cannot change, and defined constants are global in scope so there is nowhere they will not be. Once we define it, we cannot change it during the same runtime and most PHP test runners execute all their test cases in the same runtime.

That’s not to say that all constants are problematic. It’s more an issue of how we use them. Essentially, if we just stop writing if (defined())… in our code, the problem goes away.

But it’s not that easy, is it? The argument that I’ve heard most often to keep checking for defined constants is that they already exist in most large projects and so we have no choice. But this is not quite true.

The values stored in these constants are not themselves constant, and can be injected into the code that uses them. Here’s that previous example, written a different way,

function getGroceries(bool $likesPeas): string {
  if ($likesPeas) {
    return purchasePeas();
  }
  return purchaseCarrots();
}
// ...
echo "I will buy some " . getGroceries(defined('LIKES_PEAS'));

Suddenly it’s very easy to test the function! We just change its input. This is called dependency injection.

This technique is a time honored way to isolate dependence from logic. It may be less convenient because we must admit that when we need to check a constant we are actually adding a new dependency. However, noticing this gives us information, not penance. It may force us to find other ways of structuring our logic to avoid those dependencies altogether.

There is no doubt in my mind that the isolation of dependencies is critical to write code that is easy to reason about, and that doing so will reduce bugs, stress, and confusion as the code grows. When we recognize that constants created using define() are just another dependency, we can use them sparingly and isolate their usage in the same way we would for any other global or remote state which we cannot control.

(Photo by Simon Matzinger on Unsplash)

Giving more time to each thing

Lately a lot of my dharma practice has been revealing restlessness. Even when I think I’m being calm and slow and contemplative, I still am giving more thought to my Instagram-mind, or my what-do-I-need-to-do-next mind. Most of all I’ve noticed that my inclination toward efficiency in all things leads me to always be doing more than one thing at once, and this is the source of many small sufferings (Buddhist philosophy speaks of “suffering” a lot, but the word is loaded in English and perhaps better translations would be “dissatisfaction” or “stress”).

Let’s say I’m cooking dinner. I may be carefully frying onions, trying not to burn them, but I also realize I want to prepare some (vegan) sausage, so I pull that out and start to chop it up, figuring that it’s relatively little effort to do that and watch the onions at the same time. And it is, but inevitably there’s another thing; I realize that the cutting boards are not where I want them to be; someone has left them dirty in the dish washer. Ok, no problem, I can wash one off pretty quick. And I can, but then another thing; my wife is texting me asking about some papers she needs for her work, can I go find them real quick? Of course I can, but then another thing… you see how it goes.

While I tell myself that I can handle juggling all these things – and I can, and I even take a certain pride in my ability to push each thing onto a mental stack, constantly sort and re-sort their priority, and pop off what needs to be done at each and every moment – each item on the stack takes a mental toll.

It’s a tension in my belly, a furrowing of my brows, a tendency to snap at others if I’m interrupted. It’s unhappiness at the way things are. It’s stress. It’s Dukkha.

I’ve started to feel this toll in so much of my day. Microscopic things, mostly. Wanting to sip some tea while listening to a podcast. Wanting to wash some dishes while cooking. Even wanting just to think about something, perhaps a future event, when I’m busy doing something else. The thinking might be the hardest one of all.

And the solution that I’ve come to? It doesn’t require a lot of thought to figure out. Pay attention to each thing that is going on. Give it my full attention and, if I need to do something else, then totally stop doing the first thing and move on to the other. Switching isn’t the problem, it’s my resistance to stopping, my resistance to switching that is causing the suffering.

That makes it sound so easy, though. “Just do one thing at a time.” It’s cliché. For cooking onions it might indeed be easy. The hard ones are the thoughts, the emotional reverberations, and the conversations that require some time to digest (and which ones don’t, I wonder?). It’s hard for me to treat needing to think about something as worth pausing in my activity.

I’m starting to look for the feeling of that tension arising, or for the thought of “I just need to…”, and to say a resounding “no” when it appears. Well, maybe not so harsh an expression, but certainly a firm one is needed, because it’s insidious. “Oh, just this thing, it’s not really that bad” is so hard to deny, to see through the illusion of the thought. And one reason, I believe, is that I worry that I’ll be judged for it, for being slow or inefficient, or that things that matter to me or to others will not get done.

But what’s more important? Getting things done or being at peace? That’s not a trick question, or meant to be rhetorical; that’s the question that I need to ask each time I encounter these feelings. In general, when I really force myself to look at it, my answer has been “being at peace”. So my practice has become trying to find ways to just do one thing. I’ll let you know if I still manage to get things done.

What it comes down to is that the experiences in my life demand more time than I want to give. It’s challenging to stay with one experience even when others are calling. I suppose that’s the point of formal meditation, and perhaps a significant part of the recipe for a contented life.

 

Photo by Murray Campbell on Unsplash

 

Creating Sniffs for a PHPCS Standard

As a follow-up to my summary of using phpcs to lint your PHP code, this post will explain how to create, modify, and test a phpcs standard.

As a quick refresher, phpcs organizes its linting messages (warnings and errors) into “sniffs”, then into “categories”, then into a “standard”.

The official tutorial for creating a standard is here, but it doesn’t go into much detail and some parts of it are out-of-date. There’s additional useful information in the 3.0 upgrade guide but I’m going to try to do a better job here of explaining how it all works.

Continue reading “Creating Sniffs for a PHPCS Standard”

Linting PHP with phpcs sniffs

Linting is the process of using an automated tool to scan your code for problems before you commit and deploy. It is a practice widely used in the development workflow of many languages, but hasn’t much been used in the PHP of WordPress developers.

The most commonly used linter in PHP right now is called “PHP Code Sniffer”, or phpcs for short. In this post I’ll show you how to install it in a project folder, configure it, and set up your editor to display its messages.

Sniff Codes

To phpcs, an “error” or a “warning” is generated by a function that checks PHP code for certain conditions.

phpcs calls a set of related errors or warnings a “sniff”.

Sniffs can be grouped together into a “category”.

phpcs calls a collection of categories a “standard”.

To make multiple sniff standards available in a single project, install the composer package dealerdirect/phpcodesniffer-composer-installer. That will automatically use all installed standards in the current project with the composer type phpcodesniffer-standard when you run phpcs.

To install that package in a PHP project, run the following (assuming you already have composer installed).

composer require --dev dealerdirect/phpcodesniffer-composer-installer

Each error or warning in a sniff has a “sniff code” which identifies it explicitly. A full sniff code includes the standard, the category, the sniff, and the error or warning, all separated by periods.

Standard.Category.Sniff.Error

For example:

MyStandard.MagicMethods.DisallowMagicGet.MagicGet

It’s possible to refer to all the errors in a sniff by omitting the error name. It’s further possible to refer to all the sniffs in a category, or the categories in a standard, but omitting those fields as well.

Therefore, these are all valid codes:

MyStandard.MagicMethods.DisallowMagicGet.MagicGet
MyStandard.MagicMethods.DisallowMagicGet
MyStandard.MagicMethods
MyStandard

Built-in Standards

phpcs comes with several standards built-in. You can see them on the command-line by running phpcs -i. These include PEAR, PSR1, PSR2, Squiz and Zend.

WordPress has its own standard which you can install with composer as well.

composer require --dev wp-coding-standards/wpcs

I highly recommend the VariableAnalysis standard which looks for undefined and unused variables.

composer require --dev sirbrillig/phpcs-variable-analysis

Configuring Standards

When installing sniff standards in a project, you edit a phpcs.xml file with the rule tag inside the ruleset tag. The ref attribute of that tag should specify a standard, category, sniff, or error code to enable. It’s also possible to use these tags to disable or modify certain rules. The official annotated file explains how to do this.

For example, this would enable all the sniffs in a standard called MyStandard:



  My PHP project.
  

The following configuration will enable all the sniffs in MyStandard, VariableAnalysis, and WordPress.



 My PHP project.
 
 
 

Configuring An Editor

To run phpcs on a file in your project, just use the command-line as follows (the -s causes the sniff code to be shown, which is very important for learning about an error).

vendor/bin/phpcs -s src/MyProject/MyClass.php

When it runs, phpcs will report any errors or warnings it finds. That’s pretty handy, but I find that it’s even more valuable to have linters run directly in your editor so that you can see problems as you code. Pretty much all editors support this, but the method of installation depends on your editor.

For vim, I recommend you install the ALE plugin. This has phpcs support already built-in and will use the standards you have configured in your project.

For phpstorm, the linting support is built-in, but you have to configure the app to know where to look. This guide shows how to set the path and enable the inspections. The guide neglects to mention that the path setting is under Preferences > Languages & Frameworks > PHP > Code Sniffer, and that the path should be set to your local installation of vendor/bin/phpcs. It also neglects to say that the inspections are under Preferences > Editor > Inspections and that you have to set the “Coding standard” to your phpcs.xml file manually (you may also want to disable some of the existing Inspections).

For vscode, I suggest installing the vscode-phpcs extension. It will automatically detect and use your local phpcs and configuration for your project. However, note that before version 1.0, the sniff code could not be shown.

Ignoring Rules

Sometimes you’ll need to ignore or disable one of the sniffs in a standard. The official documentation explains how to do this. You can surround or prefix your code with special comments to instruct phpcs to ignore it. Note that prior to version 3.2, you could not disable specific sniffs in this way; phpcs would ignore all of them for the marked lines.

$xmlPackage = new XMLPackage;
// @codingStandardsIgnoreStart
$xmlPackage['error_code'] = get_default_error_code_value();
$xmlPackage->send();
// @codingStandardsIgnoreEnd
$xmlPackage = new XMLPackage;
// @codingStandardsIgnoreLine
$xmlPackage['error_code'] = get_default_error_code_value();
$xmlPackage->send();

In the recent version 3.2 of phpcs, this feature was greatly improved. The above special comments were replaced with // phpcs:disable/// phpcs:enable and // phpcs:ignore respectively. You can also use // phpcs:ignore on the same line as a statement.

Even better, you are able to disable specific rules with either form by listing the sniff codes (comma-delimited) at the end of the special comment. For example, this following is possible.

doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings

You can even include comments in the disabling line!

doSomethingBad(); // phpcs:ignore MyStandard.Functions.PreventBadThings -- We are ok with bad things here

If there are specific sniffs you wish to ignore for your entire project, you can configure them in the phpcs.xml file and set their severity to 0. Here’s an example of disabling the WordPress function comment rule (standards can contain other standards, so some WordPress rules are actually part of the Squiz standard).



 My PHP project.
 
 
 
     0
 

In a later post, I explain how a phpcs standard is built and how to create and modify your own. Until then, see if you can find some standards that you like and use them! Here is the phpcs.xml file I typically use right now for non-WordPress projects.

(Photo by Noel Lopez on Unsplash)

Maybe returning errors in PHP

A common pattern I see in WordPress PHP code (and probably other PHP code) is a function which does some operation on data and returns a value. For example, a function which makes a database query and then returns the resulting row.

In order to make more robust code and prevent bugs, I’ve been systematically trying to use more return type declarations in my functions. This is a problem for things like the database function described above because a database query (and therefore the function itself) can sometimes fail. In those cases, the function might return the intended data, or it might return an instance of WP_Error instead. PHP does not currently (as of 7.1) support the idea of declaring return types when multiple types are possible.

Of course, such a function could simply throw an Exception if it fails, but this might be not as safe for critical code. An unhandled Exception, even a trivial one, could kill the whole program. Returning an error object instead could keep the program running (depending on how it is used). Even if we do throw an Exception, it’s not always clear when reading the function that it can throw.

So there are two problems now. First, since the function can return multiple things, we cannot specify any return type at all.

What I would need to solve that is the ability to specify multiple return types like phpdoc, but even if I could, it doesn’t guarantee that the user of this function will notice and handle potential errors.

This leaves us with the second problem, which is the same as if the function could throw an Exception; it can be easy for someone using it to overlook that the function can fail.

Is there a solution to both these problems? Maybe. (That’s a poor joke, as you’ll soon see.)

Let’s take the following function as an example. This function accepts an array of user data and returns the color property.

function getColorFromUser(array $user): string {
  return $user['color'];
}

It’s contrived, but it’s a reasonable simplification of the database query problem, since the array property might not exist, and therefore it can fail.

So now let’s modify the function to return an error if it fails.

function getColorFromUser(array $user) {
  if (! isset($user['color']) {
    return new WP_Error('NO_COLOR', 'Color does not exist');
  }
  return $user['color'];
}

As you can see, we’ve lost both the return type and also made it possible to introduce bugs in code that calls this function if they expect a string and instead get an object.

$myColor = getColorFromUser($user);
echo 'My favorite color is ' . $myColor; // This could cause a problem if $myColor is not a string

The standard way to handle this situation is similar to using a try/catch for an Exception; if we are aware that the function can return an error, we can check for one before continuing.

$myColor = getColorFromUser($user);
if (! is_wp_error($myColor)) {
  echo 'My favorite color is ' . $myColor;
}

It’s just that in my experience it’s common to miss the fact that a function can return an error. It’s even worse if a function once returned only a value but is subsequently changed to be able to return errors. Since the normal (successful) flow of the code will not change, no change is actually required anywhere the function is used. This makes type errors not only possible, but likely.

But what if we instead returned a wrapper object around the data? Let’s call it a Maybe. (See? There’s the joke.)

function getColorFromUser(array $user): Maybe {
  if (! isset($user['color']) {
    return Maybe::fromError(new WP_Error('NO_COLOR', 'Color does not exist'));
  }
  return Maybe::fromValue($user['color']);
}

Now we can have a return type, which can help prevent bugs inside the function. It’s not perfect as it doesn’t explain what types of values the object can contain, but it’s better than nothing. (To be fair, if we wished, we could create specific versions of Maybe for different values, like MaybeString, but I’m just going to keep it simple for now.)

Your first reaction might be that it also creates an inconvenience for the user of this function, because in order to extract the value of this data, someone has to do it explicitly.

But that small inconvenience means the developer must know about the possible error.

The example might then look something like the following. The condition required is similar to using is_wp_error(), but it’s more probable that the developer will remember to add the condition because they are forced to use getValue() on success.

$myColor = getColorFromUser($user);
if (! $myColor->isError()) {
  echo 'My favorite color is ' . $myColor->getValue();
}

This is not a perfect solution, and I’m certain that many developers will balk at having to add a pattern like this to their workflows when it’s not a standard part of the language. Personally I think it would be worth the discomfort to adopt this sort of construct when the benefit would be code that’s significantly less likely to have type errors. It probably depends on how careful you need your code to be. What do you think?

PS: It’s perhaps relevant to mention that there are functional programming concepts that are similar to this implementation, but which take it much further. My suggestion here is a very minimal interpretation that might be easier for some developers to grok. A more accurate name for this concept, matching existing patterns, is a Result.

Here’s how the Maybe/Result could be written:

(Photo by Caleb Jones on Unsplash)

Functional Dependency Injection in PHP

Having become used to the convenience of passing first-class functions around in JavaScript to make other functions decoupled and easily testable, I was wondering if we could do the same thing in PHP.

Of course, PHP technically has first-class functions as well, but the syntax is a little awkward, since the functions must be referenced as a string (and sometimes as an array).

Often I have some logic that can easily be contained in a pure function, and while I could put it in a class method, it’s not uncommon that the function doesn’t feel like it belongs to any particular class.

In these cases I tend to create “helper” classes. Essentially, I create a god class which is really just there to namespace its functions. If there’s a group of functions I want to inject, I might use regular class methods for this purpose, injecting an instance of the class. Otherwise, I use static methods. It occurred to me that maybe I could do the same thing with plain functions and actual namespaces.

JavaScript

In JavaScript one could do the following (this example is a bit contrived, but bear with me).

export function getGreenTea() {
    return 'green tea';
}

export function getOolongTea() {
    return 'oolong tea';
}
import {getGreenTea, getOolongTea} from 'tea-types';

function makeTea(getTea) {
    console.log(getTea());
}

makeTea(getGreenTea);
makeTea(getOolongTea);

PHP instance methods

Here’s how it could be done in PHP with classes and instance methods.

class GreenTea {
    public function getTea() {
        return 'green tea';
    }
}

class OolongTea {
    public function getTea() {
        return 'oolong tea';
    }
}

public function makeTea($teaType) {
    echo $teaType->getTea() . "\n";
}

makeTea(new GreenTea());
makeTea(new OolongTea());

PHP static methods

Here’s how it could be done with classes and static functions.

class TeaTypes {
    public static function getGreenTea() {
        return 'green tea';
    }

    public static function getOolongTea() {
        return 'oolong tea';
    }
}

function makeTea($getTea) {
    echo $getTea() . "\n";
}

makeTea([TeaTypes::class, 'getGreenTea']);
makeTea([TeaTypes::class, 'getOolongTea']);

PHP namespace functions

Lastly, here’s how it could be done with just namespaces. I think this is the closest to the JavaScript version, and doesn’t require creating unnecessary classes.

namespace TeaTypes;

function getGreenTea() {
    return 'green tea';
}

function getOolongTea() {
    return 'oolong tea';
}
namespace TeaMaker;

require('./TeaTypes.php');

function makeTea($getTea) {
    echo $getTea() . "\n";
}

makeTea('\TeaTypes\getGreenTea');
makeTea('\TeaTypes\getOolongTea');

Of course, this technique might not be the best choice for some situations. If there is any shared state or expensive repeated operations between functions, then they should be in a class and the methods should not be static.

Also, passing lots of dependencies to functions can sometimes be verbose and hard to read. In these cases it can be easier to pass the dependencies as a single object instance instead.

Finally, if there are several unrelated helper functions which are used in multiple places within the methods of a class, it can be more readable to pass all the helpers to the class constructor at once as an object (as though they were related).

Still, I think that passing functions as dependency injection is an under-used technique in PHP. I know it’s not the least bit Object-Oriented, and PHP is much more of an OOP language than JavaScript. In my opinion, however, the power of OOP is shared state and polymorphism and pure functions need neither.

(The image for this post is by 童 彤 on Unsplash.)