January 2008 Archives

Or, since I haven’t made much recent progress at it, “What I’ve been trying to do while doing all the other stuff required by life”: I’m writing my own blog engine/CMS thing. I’m doing this for several reasons. First, it’s partly because I think it’s a fun thing to do and it’s a chance to play around with Perl and web stuff and maybe learn a thing or two. Second, it’s partly because none of the existing tools work as well as some older tools that I can’t really use anymore, due to platform choice or rotten code. Finally, in a big way, it’s because of this talk that Faisal Jawdat gave at the 2007 Pittsburgh Perl Workshop about Bear, which got me to realize that I can write this, and even release it, without it having to be the be-all end-all for everybody. I can do something that works for me and if others find it useful, fine; if they don’t, also fine.

So. It’s called Saguaro. Fairly standard template-based static content generation system, using a modified Markdown and a few other things that I’ll semi-document at some point. Doesn’t all work quite right just yet, no tests to speak of, in general needs quite a bit of work, you know the drill. Lots of my discretionary time will be going towards getting this to a place where it works well enough that I can run this site using it, at which point I’ll start porting all my old content into a form that it can deal with. If everything goes well, I’ll hopefully finish some time this year; we’ll see. There’s anonymous SVN available; holler if you want in and can’t figure out the URL.

See you in a couple weeks.

been a while.

As I mentioned last week, I’ve been working on a little reading list management tool. I’m using App::Cmd as the framework, which has been a somewhat frustrating but ultimately worthwhile choice.

I first learned of App::Cmd at the Pittsburgh Perl Workshop, through a talk given by the module’s author Ricardo Signes. The slides from that talk are about the best App::Cmd documentation out there, although App::Cmd::Tutorial also has some useful bits, and the module documentation itself isn’t bad by any means, just a little light on example code.

For BookList I didn’t do a lot of up-front design work — I was basically designing as I went and learning App::Cmd at the same time. As a result, I ended up implementing several commands with only the most rudimentary tests — basically, if the command module loaded, I was happy. Since BookList is getting towards a 0.1 level of functionality and I’d like to release it, I spent the past couple days renewing my appreciation of “test first” development by going back and writing all the tests I skipped over the first time through.

Because of the way the framework works, testing App::Cmd code is a bit different than testing library-level routines. The talk I pointed to above has a section on testing (around slide 115, for those of you who want to check it out), which references a nifty looking module called Test::App::Cmd. Unfortunately, the module doesn’t appear to be publicly available yet. (This might have been mentioned at the talk; I don’t recall. Any status updates are welcomed.)

After poking around on CPAN, trying to find something to provide some scaffolding for my tests, I ended up finding a module called Test::Output. I used that and the sample test code in the talk to write a bunch of tests that looked like this:

use Test::More     qw/ no_plan /;
use Test::Output   qw/ stdout_from /;

use Booklist::Cmd;

my $error;
my $stdout = do {
  local @ARGV = ( 'authors' );
  stdout_from( sub {
    eval { Booklist::Cmd->run ; 1 } or $error = $@;
  } );

like $stdout , qr/^###  #bk  author/ , 'see expected header';
ok ! $error;

and while that mostly worked out okay, I ran into trouble with some of my error-handling code. When writing libraries, especially for my personal use, I tend towards the low-budget “croak() and let the caller deal” method of exception handling. But for something that’s going to be more application-level, I wanted to print messages to STDERR and then exit() with a non-zero status. This doesn’t play well with Test::More or Test::Output, neither of which trap calls to exit().

After a bit more CPAN searching, I found Test::Trap which is excellent for testing App::Cmd code. The above code rewritten to use Test::Trap looks like this:

use Test::More    qw/ no_plan /;
use Test::Trap    qw/ trap $trap /;

use Booklist::Cmd;

trap {
  local @ARGV = ( 'authors' );

$trap->leaveby_is( 'return' , 'exit normally' );
$trap->stdout_like( qr/^###  #bk  author/ , 'see expected header' );
$trap->stderr_nok( 'nothing on stderr' );

That second code block is a lot cleaner and easier to understand than the first one (not to mention being fewer LOC while doing an additional test), and the accessor/comparison methods (leavebyis, stdoutlike, etc.) from Test::Trap are both easy to write and (if you know anything at all about idiomatic Perl testing code) trivial to understand.

I’m going back now and rewriting all my previous Test::Output tests to use Test::Trap — but I’ve also learned another lesson here: my last test is currently failing, because I wrote it beforeimplementing the command it tests.

  • Wikipedia on ‘Runbook’. Chandler project ops runbook
  • 10 blogging tips from Jorn Barger. (When did Robot Wisdom grow a tagline reading ‘judaism is racism’? Oy vey.)
  • Account of auto-waterboarding experiment. Scary.
  • Rails is a Ghetto. You knew that already.
  • MJD on kids and the Santa fable. We have a similar position about the kids, Santa, and the truth; this year was the first year it really became an issue. I’m not sure TheOlderChild believes us when we say Santa is just a story. 8^/=
  • Eventually Consistent. You can’t always get what you need.
  • It was twenty years ago today. I learned this year that TheYoungerChild and Perl share the same birthday. I am unreasonably happy about this for some reason.
  • And speaking of Perl, just in case you’ve been under a rock, Perl 5.10 is out. One of these days I’m going to write up the collective wisdom on how to deal with managing Perl deployments in a sane fashion in a large enterprise environment from the sysadmin point of view — just as soon as I find some collective wisdom on the subject, as opposed to the suck I keep running into when dealing with the problem…
  • AskMeFi: 2 player games on the Wii? For future reference, now that I finally got around to buying additional WiiMotes.
  • What a modern collaboration toolkit looks like is ESR semi-lambasting the GNU Emacs development community and culture by comparing it to a more “modern” devteam. Interesting in an anthropological way, if nothing else. (If you want to follow the whole thing, you’re probably better off digging up the thread via Gmane, which seems to have a much better web-based interface for that sort of thing…)

I kept track of my reading for 2007 using a little YAML file and a standard data layout for each book. My intention was always to write a little bit of code to parse this and throw it up on the web, but I never quite got around to it until today. The little bit of code isn’t really ready for primetime yet, but I can say I read 57 books last year, making this at least the second year in a row I’ve managed to average 1+ book a week. Go me.

Lots of other stuff I’m hoping to accomplish in the new year, naturally, but a lot of that has to do with doing stuff rather than talking about doing stuff, so I’ll just leave it until I’ve actually done some stuff. Then we’ll talk…

Best wishes to you and yours in the new year.