This morning I went to hear Tom Gilb speak. When I first heard he was coming to Belfast, I was quite excited; but then I heard he was speaking on software inspection, which sounded quite dull. It turned out to very interesting, although (or perhaps because?) he only managed to make it through less than 20% of his slides!
After pointing out the "so obvious, that no-one ever gets it" fact that inspections differ from reviews in that inspections are checking against a well defined 'standard', Tom proceded to give his three rules for inspecting a requirements document:
I've been immersed in the whole XP / Rapid Development culture for so long that I'd almost forgotten that there were people who still used 800 page requirements documents to write their design specs etc. But it's interesting to see the way that XP has taken a lot of the work that people have done in the Big Process Methodology field and totally shifted the goalposts.
Clear enough to test is a classic example of this. XP pretty much says that requirements *cannot* be untestable, as the requirements get expressed as tests! If something passes all the tests, then it's finished. If it's missing something, then write a test that exposes it.
As a developer, I've found this to be a great mindset to code under. I'm a complete convert to test-first programming. However, I haven't yet managed to convert clients to the mindset for acceptance testing. It's generally hard enough to get people to tell you what they think they want, without them having to come up with repeatable tests that 'prove' that the system works. I still like the idea though - maybe I just need to come up with a way of presenting it to a client that makes it sound good!
In other news, it seems my Test vs Overload problem boiled down to the fact that when overloading you need to either provide a sensible method to call for each overloadable thing, or provide a 'fallback'. Adding a fallback made it all work.
But I also learned in the process that perl treats
print scalar(my($foo) = "bar");
very differently than
print scalar(my $foo = "bar");
So Test::More's ok function, which is prototyped $;$, coercing scalar context, treats these differently too...
I've also had problems recently with Template Toolkit and Class::DBI not playing well together. For the most part, they're a wonderful combination - pass a single Class::DBI object representing a row of your database into your template and you have methods representing each of the columns, as well as more complex structures representing your relationships:
[% FOREACH track = cd.tracks %]
- [% track.title %] by [% track.artist.name %]
[% END %]
One of TT's (many) wonderful features, is that it just DWIMs on the '.' character, giving you a hash element, or array element, or call a method on an object or whatever it needs to do (the above TT code wouldn't change at all if I had a hash of hashrefs instead of an object containing other objects etc..). However, this means that when you pass it a one element list, it will treat it as a long scalar.
In normal circumstances you can call .list on this to force TT to treat it like a list, and access .first, or suchlike. But, only if it's unblessed. If it's blessed it'll try to call the first() method instead (and fail if you don't have such).
Or should I say, 'it used to try', as a couple of posts to the TT list about this, and Hey Presto, Andy has patched everything to just DWIM.
I really love the world where you can leave the office at night with code that doesn't work, and return in the morning to discover it can, without your code even having been touched in the process :)