April 2012 Archives

The Price of Cleverness (YAML is not Safe)

Today I wasted a few hours tracking down this delightful bug:

Undefined subroutine &main::main:: called at 
...lib/site_perl/5.12.4/YAML/Mo.pm line 5.

So what does YAML::Mo line 5 look like?

That's right. That's line 5. I've wrapped it to make it easier to read. When you load the latest YAML, you load YAML::Mo and that contains the above monstrosity. And it has a serious bug. Do you see it?

The Simplest Thing That Could Possibly Work

It should go without saying that when you are writing a book, you need to know how long the chapters are. I'm writing mine in vim, with various customizations to fit the needs of the book. However, I then need to convert my book into MS Word format. As I'm using Word 2008 for Mac, and as its the only version that does not have a scripting language built-in, formatting my plain text to the publisher's requirements is a long, tedious process. There are different headings, code, sample exercises, tables, images, "Try it out" sections, and many tiny, tiny details that need to be formatted correctly to ensure the book can be laid our properly.

In order that I can properly estimate how many pages I've written, the publisher provides an AppleScript program that is 2,204 lines long. You start it running, answer a few questions, and then leave and do something else for a while. It runs over your entire chapter, analyzes the various styles, notes issues that may occur, and after a few minutes, it comes back with an estimated page count.

I wrote a Perl script to list the "Table of Contents" sections for a given chapter. This script also estimates the page count. Here's the code I wrote to do it:

printf "Estimated page count is %d\n" => int( $lines / 45 );

It's rarely more than 2 pages off and that's close enough for my needs.

Reading the Federal Register with Perl

In case you're curious:

% grep -rli assassin federal_register | wc -l
      50

That's 50 mentions of "assassin" in the US Federal Register since early 2000. There's some interesting stuff buried in this publication.

Recently I wrote a post about more Americans giving up citizenship than reported. While I don't have exact numbers (they're hard to find), I managed to put together some information that seems to show that far more Americans are giving up citizenship than the Federal Register reports, but I'll skip the background.

Basically, I decided to download the entire Federal Register in XML format (it's in the public domain, too). Unfortunately, this snippet of code is not going in the book.

Explaining Web Programming via Plack

I'm currently writing Chapter 15 of my Beginning Perl book and it's about Web programming. The first part is about server-side software and the second part is about clients.

When I finally sat down to write about Web applications, I thought of what I should do. Some of you may remember my old Web programming course, but that was written around CGI and just wouldn't do. So I need to use something modern, but since I have a deadline, that means writing about something I know fairly well. That seemed to leave me with two primary options: Catalyst or Dancer. The latter is easier to use, but still "magical" enough to hide things I wanted to explain. Exploring other options would mean learning to use them and possibly missing a deadline.

That's when inspiration struck.

Avoiding use_ok in t/00-load.t

There's a discussion on Perl-QA about whether the use of use_ok should be discouraged. I argue that it should be. It really doesn't gain us much, it's historically been buggy, and simply using the module is enough to cause a test failure if the module doesn't compile. So someone asked how to write this t/00-load.t if we didn't have use_ok:

#!perl -T
# -*- mode: cperl ; compile-command: "cd .. ; ./Build ; prove -vb t/00-*.t" -*-

use Test::More tests => 5;

BEGIN {
  use_ok( 'Test::Trap::Builder::TempFile' );
  use_ok( 'Test::Trap::Builder::SystemSafe' );
SKIP: {
    skip 'Lacking PerlIO', 1 unless eval "use PerlIO; 1";
    use_ok( 'Test::Trap::Builder::PerlIO' );
  }
  use_ok( 'Test::Trap::Builder' );
  use_ok( 'Test::Trap' ) or BAIL_OUT( "Nothing to test without the Test::Trap class" );    
}

diag( "Testing Test::Trap $Test::Trap::VERSION, Perl $], $^X" );

Here's a cleaner solution that relies on Perl's "use" builtin and the "if" pragma.

use Test::More tests => 1;

my $ok;
END { BAIL_OUT "Could not load all modules" unless $ok }
use Test::Trap::Builder::TempFile;                                                                                                            
use Test::Trap::Builder::SystemSafe;
use Test::Trap::Builder;
use Test::Trap;
use if eval "use PerlIO; 1", 'Test::Trap::Builder::PerlIO';
ok 1, 'All modules loaded successfully';
$ok = 1;

Yeah, I like that.

Naturally, it doesn't work if you're trying to dynamically discover the module names, but it could be made to work with that, too.

eval "use $module; 1"
  or BAIL_OUT $@ // "Zombie error";

Thanks to Ruud H.G. van Tol for correcting my eval.

When the speed of light is too slow

I'm currently working on a Real Time Bidding system. Basically, when someone visits a Web page, that page may cause a bid request to be sent out to multiple ad bidders and they bid on who gets to place the ad. For my system, I have to respond withing 100 milliseconds to be eligible to participate in the auction. That's when life gets interesting.

About Ovid

user-pic Have Perl; Will Travel. Freelance Perl/Testing/Agile consultant. Photo by http://www.circle23.com/. Warning: that site is not safe for work. The photographer is a good friend of mine, though, and it's appropriate to credit his work.