February 2012 Archives

Test::Builder2 vs CPAN and How You Can Help

Test::Builder2 is now down to two issues.

  1. The problem of using Mouse
  2. The problem of backwards compatibility

The former is complicated, but suffice it to say TB2 cannot rely on Mouse or Moose or Moo. It's being solved by writing an OO compiler, something which will generate accessor methods and roles at build time rather than relying on a runtime compiler. This should also solve TB2's less than ideal startup time. It might be Mite or it might be Moo, but the problem is being taken care of.

The second is harder and is what I call "Test::Builder2 vs CPAN". Because Test::Builder has been around or so long, and so much depends on it indirectly, there's a lot of not entirely documented behavior being relied on. We've been using CPAN modules as a broad test suite right along for this reason. TB2 has the potential to seriously break a lot of module's test suites, so it's best to get it as right as possible before stable release.

A Real Developer Challenge

Spotify is having a coding challenge to find "top-notch talent to join our NYC team". The challenge is to solve the most algorithmic puzzles in four hours... alone. "You may not cooperate with anyone, and you may not publish any discussion of solutions." What sort of developer will win this competition? Someone who is quick, dirty, has a mathematical mindset and lucky enough to write something that happens to work for the test data set. The "rockstar". Is this somebody you want on your team? Would you want to maintain their code?

Last year while on contract, the company in question was passing around their coding problem they used to test new hires. It was pretty typical stuff: give the data going in, the data they want out, and write a little program to do the transform. They even supplied most of the program, including a test; the prospective hire just needed to write one sort subroutine which could deal with "Low", "Medium" and "High" as well as numbers.

Predictably, this halted all coding in the office for a solid half day while everyone figured out the most clever way to sort the data. My opus was to observe that the input data was already sorted, so I redefined the shuffle() routine. The best one was from a co-worker who observed that "Low", "Medium" and "High" sort correctly by their last letter in reverse order. It was fun for us, but it wasn't very useful.

This is a pretty typical coding problem used to judge potential hires, and it sucks. All it tells you is the candidate is not completely incompetent. Why do we keep using them? They're easy. They're easy to think up, easy to judge and easy to administer. They're also the sort of clean, algorithmic problems a stereotypical programmer loves to solve. Do they have anything to do with detecting a good developer? No. Can we fix it? Yes!

True + True == 2

I've seen lots of new Perl programmers confuse 1 and true before, usually something like this:

do_something if boolean_function() == 1;

This is not only redundant, but it's also brittle and redundant. In Perl, it's very easy for a boolean function to return something other than one.

sub has_stuff {
    ...
    return scalar @stuff;
}

This code I found today in Module::Build::Base takes the cake.

if ( $self->check_prereq + $self->check_autofeatures != 2) {

(Yes, I fixed it)

UPDATE: Whoops, I broke it! As rsimões pointed out in the comments, the original does not short circuit and my change does. That was not a bug, both check routines should always run (a consequence of the checks having side effects). I had to think about it a bit, and the simplest thing I came up with is:

if( grep { !$_ } $self->check_prereq, $self->check_autofeatures ) {

Which goes to show, and I should have known this myself, don't assume the author is an idiot. There's usually a reason why they did what they did. Find it before touching the code.

About Michael G Schwern

user-pic Ya know, the guy who tells you to write tests and not use MakeMaker.