I’ve just written my first ‘real’ real post for the new Freedom is in Peril website. I’ll try and keep the political stuff on that blog from now on, but if you’re at all concerned about the erosion of what has traditionally, if cornily, been called “British Liberty”, then I hope you’ll swing by, and link to, the new site.
I’ve just pushed the second version of Test::Class::Sugar (first discussed here). It’s pretty much as discussed in the original article, but after some discussion with David Wheeler, I’ve dropped the +uses clause from the testclass declaration in favour of less DWIMmy (and thus easier to explain behaviour).
I’ve also introduced a defaults argument at use time. The only working default in this release is one which lets you specify the prefix used to derive the test class name from the class/module under test. I’ve documented a couple of extra and so far unimplemented defaults as well.
I got a bit of stick on IRC last night for some of the choices I’d made when I was writing Test::Class::Sugar, in particular because one of the prerequisites is chromatic’s handy and opinionated Modern::Perl module. The ‘controversial’ aspect of Modern::Perl is that, when you use it, your code won’t run on any Perl before Perl 5, version 10.
The thing is, I don’t care about older perls any more. Version 10 features like and // are too convenient to fart about writing circumlocutions just to run on a version of Perl that I have no intention of ever using again.
In which your correspondent does magical battle with the guts of Perl and emerges bloodied, but unbowed with a useful principle to code by.
Skip to the conclusion if you’re uncomfortable with the guts of the Perl runtime
#
Test::Class had me tearing my hair out earlier. There I was, happily transforming
test something {
ok 1;
};
into something very like[1]:
\*test\_something =
Sub::Name::subname(
'test\_something'
=> sub : Test { ok 1 }
);
through the magic of [`Devel::Declare`](http://search.cpan.org/dist/Devel-Declare), but Test::Class didn't seem to be playing fair. Instead of letting my tests run happily, it was complaining that it:
> cannot test anonymous subs - you probably loaded a Test::Class too late (after the CHECK block was run). See 'A NOTE ON LOADING TEST CLASSES' in perldoc Test::Class for more details
The thing is, I wasn't loading Test::Class too late. The problem is that, at the point I applied the `Test` attribute to my sub, the sub didn't have a name and, because of the constraints you're operating under when you're using `Devel::Declare` to do code transformation, there was no obvious way to give it a name in time.
#### Incompatible magics
The trouble is, Test::Class does what it does through the magic of compile time code attributes, and, further, it relies on the fact that if a perl subroutine that gets inserted into the symbol table like this:
sub has\_a\_name {...}
Then, when you get hold of a reference to that code by other means (say, in the subroutine that handles the setting of an attribute, that code ref knows its own name. However, if a subroutine that ends up in the symbol table like this:
\*anonymous\_ref = sub {...};
Doesn't know its name, unless you take advantage of the [`Sub::Name`](http://search.cpan.org/dist/Sub-Name) module.
So, in my generated code, I was giving my coderef a name, but it was happening to late. At the point that `Test::Class::Test` method was seeing the coderef, the coderef was anonymous.
My magic and Test::Class's magic were incompatible.
The thing is, both sorts of magic are really just sugar for some pretty mundane donkey work. Test::Class does what it does through attributes because no flesh and blood programmer in their right mind would want to write something like this every time they wanted to write a test method:
sub test\_something {
...
}
*PACKAGE*->mark\_as\_special\_method('test\_something', 'test', '3');
In fact, `mark_as_special_method` doesn't even exist as its own subroutine. The code that marks a method as special is just part of the body of the `Test` attribute handler.
### Conclusion
Which brings me neatly to my conclusion.
When you're designing a module that does anything magical, consider starting with a mundane core API that handles the business side of things. Then layer your magic on top of that API. Then document the API and the magic. Obviously the magic bits go up front in the docs, and the API goes in its own section (or even podfile) down at the bottom, where only eejits like me, who want their magic to work slightly different to yours, will bother reading it.
Obviously, I'm motivated by an issue I'm having with a particular module from CPAN, but the principle of separating the magic and the mundane is applicable everywhere. It's called Separation of Concerns, or The Single Responsiblity Pattern. I call it a [Just Story](http://www.bofh.org.uk/2003/08/01/the-fine-art-of-complexity-management).
You'll find the pattern in well designed websites that are using unobtrusive javascript to wave an AJAX wand over the site. You'll see it woven through books like The Structure and Interpretation of Computer Programmers - where it's called an Abstraction Barrier.
#### Patches sent
It turns out to be very easy to add `mark_as_special_method` (though I actually wrote it as 'add\_testinfo' in the patch) to Test::Class. It's about as straightforward an Extract Method refactoring as I've ever done - even without automated tools, I managed not to fuck it up. There's a patch in [Adrian Howard's](http://www.twitter.com/adrianh) inbox, and I'm hopeful that it'll be applied soon.
Check out the [osfameron fork](http://www.github.com/osfameron/devel-declare) of Devel::Declare for the beginnings of some decent documentation which explains what's going on.
[1] Not exactly - that's the result of calling the shadowed `test` subroutine which was the result of the code transformation.
One aspect of coming back to Perl for ‘recreational’ programming is that if, like me, you’ve declared war on @_ and boilerplate code, then testing can be somewhat trying. The Perl testing framework that best fits my head is Test::Class, which is an excellent Perlish implementation of xUnit style testing. If you’re unfamiliar with the, library, Ovid is writing what’s shaping up to be an excellent series of introductory articles about it at http://www.modernperlbooks.com/.
Here’s something interesting. This is the test directory from the very first version of Perl, released in 1987 and described by Larry as ‘a “replacement” for awk and sed’. Day one of Perl, and we already have the bare bones of the Test Anything Protocol and a prototype for Test::Harness in the TEST file.
If we truffle about in the various other branches we find other useful milestones for module developers:
5.000, in 1994 came with the first iteration of h2xs which could be used to generate the basic boilerplate for a perl module. Even today, with more sophisticated module starters available, you won’t find a CPAN module of repute that doesn’t follow the basic directory structure laid down in this utility. ExtUtils::MakeMaker generates a Makefile with a test target which runs all the tests in the t subdirectory
5.002, in 1996, h2xs starts stubbing test.pl
5.003_12, late 1996, first version of CPAN in the Perl distribution. From day one, CPAN would not install a module if any tests failed, unless you forced it.
It doesn’t matter what language you program in, there’s one very important thing that you should do if you want to get better at your craft.
Read. The. Fucking. Manual.
Seriously. Tutorials are good. Blog articles can be good. Code snippets are probably better than a poke in the eye with a fecally decorated sharp stick.
But the language reference? That’s gold. Read the docs. Read the source. Whatever you do, get the fundamentals down.
Let’s say you’re writing a ruby library. Something you want and expect others to use. Here’s how to reduce those others to incandescent rage:
require 'rexml'
include REXML
module MyShinyModule
...
end
No. Not no how. Not never. You just crapped in my namespace and stomped on who knows how many of my own classes. Now, `include` is a fine and dandy thing, and it certainly has its uses, but using it at the top level of your library files is not one of them.
Ahem.
Can anyone guess which library has been wasting my morning?
One of the people who make me think that Perl is still worth knowing is chromatic, the ex-editor of O’Reilly’s perl.com. He’s one of the core team who are working to bring the Perl 6 Christmas, a vector of test infection, an extreme programming practitioner and, right now at least, no longer on Giles Bowkett’s christmas card list.
When I wrote the Healthcheck: Perl for (oh ghod, they’ve rebranded) The H, I mentioned that O’Reilly hadn’t announced Perl: The Good Parts yet. This was an allusion to something chromatic had said when I interviewed him for the article - at the time he was pitching that very book, but it seems he got knocked back.
‘Moose for Ruby Programmers’ was the programmed title for the talk I gave at the London.pm technical meet on Thursday, but that was something of a stalking horse for the real title, but I’ll save that for the end of this writeup.
I’ve said this before, and I’ll no doubt say it again, but the main reason I started programming in Ruby was that I got fed up of unrolling @_. From a Perl programmer’s perspective, Ruby is like Perl 5, but with a way better object system out of the box.
So, it turns out that there’s a recording of my MooseX::Declare talk at the London.pm techmeet last night. And, on listening to it, I sound rather less incoherent than I thought I did while I was delivering it (still plenty of places where I could improve. Must remember to always repeat the questions in full…), but I’m happy enough with it that I’m looking into synching it up with the slides and making a slidecast, which will probable take longer than is sensible.
The Prags will tell you that you should learn a new language every year, and I think they have a point. This year though, I’m going to do things slightly differently. If you read the Healthcheck: Perl article I wrote for Heise Online then you’ve probably worked out that my language for 2009 is Perl 5, version 10 (hopefully it’ll be version 10.1 real soon now). I’m still paid to write ruby for AmazingTunes in my day job, but Perl’s the language I learned to program with and developments around Moose and its extensions mean that Perl in 2009 is a different language from the one I pretty much stopped using a couple of years ago.
Giles Bowkett's just written up [an example](http://gilesbowkett.blogspot.com/2009/01/classic-song-travels-through-time.html) of the way that [sampling is an essential part of modern music](http://gilesbowkett.blogspot.com/2008/09/copyright-violation-every-artists.html) and he's right. But he doesn't go far enough really. Sampling has always been an essential part of all musics. What's the twelve bar blues form after all? Different artists put their own spin and lyrics on top of it, but it's always the same chord structure and it's often the same words forming the backbone. I don't know about you, but I can't hear the words "I woke up this morning" without expecting a blues to follow.
Have you ever tried to run Rails, Rspec, Rake or, for that matter almost any Ruby library or application that you've ever heard of with the -w flag? How about running Rails with taint checking on?
They aren't exactly pleasant experiences.
Meanwhile, over in Perl land, it's a very rare module indeed that isn't at least clean under -w and, where appropriate, taint friendly. It would be a very irresponsible Perl Monger indeed who wrote a web framework that didn't assume it was going to be running under the -T flag. Warnings and taint checking are annoyances, and sometimes they're flat out wrong, but more of the time they're useful. Which is why, in Perl, you'll sometimes see blocks of code like:
So, because I'm sure that there's a better way of drying up my rails apps, I've been porting [Magritte](http://www.lukas-renggli.ch/smalltalk/magritte) to Ruby (given a good metadescription of your models and judicious application of the visitor and interpreter patterns, it's amazing what you can do). Now, Magritte comes with a pretty decent test suite in its Smalltalk box. However, that test suite makes serious use of inheritance. Several tests of the leaf classes in the Magritte description hierarchy define maybe three helper methods which parametrise the tests they inherit from their parent test suites.
So, remind me, what's the rationale for always using the optional ; when you're writing Javascript? The only reasons I can think of, off the top of my head are, "Because you'll break minifiers without it" and "Because Douglas Crockford doesn't like it". Well, broken minifiers that can't parse the language correctly can kiss my fat hairy arse and argument from authority cuts little ice here.
[Gareth Rushgrove](http://morethanseven.net/) pointed me at [an article](http://icanhaz.com/semicoloninsertion), which suggested that it's because Javascript will insert a semicolon after the `return` in:
We’ve just spent the weekend on one of Robin Wood’s spoon carving workshops, which was my 41st birthday present from Gill. It was great fun, if a little tiring. There is something primally satisfying about turning a piece of wood into woodchips. Getting a spoon or spatula at the end of the process is a huge bonus. We came away with a bag full of more or less decent treen, a couple of woodcarving knives and a burning desire to own one of Robin’s small drinking vessels.
There’s a refactoring principle that states that, when you start doing the same thing for the third time, you should refactor to remove the duplication.
I’m starting to wonder if there’s a Smalltalk principle which states that, when you start doing the same thing the second time, you should search the image for the obviously named method (or use the method finder to find some candidate by feeding it some inputs and an expected answer), because the odds are good that it’s only the second time for you - it might be the millionth time for the image you’re working in.
The Alpha Course people have been running a bunch of poster ads built around the slogan “If God did exist, what would you ask?”. The posters are filled with anodyne questions like “What’s the point?” or “Is this it?”.
They also tend to have large amounts of white space on them - I’m sure there are enterprising graffiti artists out there who look upon that as a fine opportunity.
So, here’s a few questions I’d ask god, if it existed: