Latest posts

Unix tips: handling script output

Wow I've not blogged in ages! Here's a couple of quickies that I seem to rediscover every 6 months and promptly forget - hopefully writing them here will make them stick in my head.

Logging output to disk

Obviously to log the output of some process to disk you'd normally use > or >>. However, sometimes you want to also use the output for some other process.

In instances like this you'd use tee:


php my-script.php | tee -a /var/log/my-script.log | other-script

The output of my my-script.php will be both written to my my-script.log, and piped to other-script for further processing (the -a flag means the output is appended to the log rather than it being overwritten).

Disabling comments on this blog

I'm getting really high volumes of comment spam at the moment, and don't really have the time to try and work out how they're evading the reCAPTCHA on the comments form, so I'm just turning it off for now.

I'm also in the process of thinking about what to do with this site, given that I'm not updating too regularly, I tend to stick to one-liners on Twitter a lot more, recently.

A great customer service experience from Amazon

I got a Kindle around the start of the year, and I guess it's something I could write about separately but I'm fairly sure it's the device I've had that I've got the best entertainment value out of in terms of cost per pound.

If you've seen the ads, you'll come away with the impression that the Kindle can be shoved in a draw, licked by a dog and generally thrown around the place so that's how I treated mine.

Last week I was talking about the Kindle to some workmates and really praised its rugged form and overall resilience - in retrospect it was asking for trouble. The very next morning I took it out of my bag and saw it looking like this:

Broken Kindle

Use labelled groups in Regular Expressions for clearer code

I keep seeing this sort of pattern in PHP code, when people match on Regular Expressions:


$orderNumber = 'CLK-TEST001-030';
$pattern = '/([a-z]+)-([a-z]+([0-9]+))?-([0-9]+)/i';

if (preg_match($pattern , $orderNumber, $matches)) {
    echo "Prefix was ".$matches[1]." and duration was ".$matches[4];
} 

The problem here is that the numbers 4 and 1 are kind of cryptic. Furthermore if the expression changes in future I'll probably need to go through my code and redo the numbering.

A better alternative is to name the groups inside the expression:


$orderNumber = 'CLK-TEST001-030';
$pattern = '/(?<prefix>[a-z]+)-([a-z]+([0-9]+))?-(?<duration>[0-9]+)/i';

if (preg_match($pattern , $orderNumber, $matches)) {
    echo "Prefix was ".$matches['prefix'].
        " and duration was ".$matches['duration'];
} 

This way if the expression gets changed, I can still use the same named fields in my matches in the subsequent code.

Using partial mocks in PHPUnit to test tricky code

At work we've been going through the fairly painful process of adding unit tests to existing code. I'd like to share one technique I've found useful, a way of testing methods that at first glance look like they have too many dependencies to easily get under test.

I'll be giving these examples in PHPUnit but any xUnit framework should be able to do something similar.

Consider a method like the following, which is the sort of thing you might have trouble seeing how to test:


class MyClass
{
    public function getDataAndPublishRemotely()
    {
        $data = DataStore::getUnpublishedData();
        
        $service = new SoapClient($SOME_WSDL);
        $service->publish(preg_replace('/[^0-9a0z]+/', '', $data));
    }
} 

So this is doing some sort of DB call, then calling a SOAP service and publishing a cleaned-up version of the result. What makes this hard to test is the fact it's got two solid dependencies - a static call to some sort of DataStore layer and a direct instance of a SoapClient class.

Eventually the way to fix this sort of thing is to inject both of those dependencies separately, but that's too big a refactoring to tackle straight away. When you're modifying a class to get it under test you want to do small, easy-to-understand changes and get it under test ASAP.

One approach to getting it tested is to split the functionality that you think you can test into a separate method, like so: