Ninja Code

As this is only my second post—my first merely being a plug for a Damian Conway talk at my local Perl Mongers meeting—I thought I’d keep it short and silly.

At OSCON 2008, Amazon had a prominent booth advertising heavily that they were hiring. They didn’t want to hire just anyone. No, the question posed on the large sheet of poster board was, “Are you a ninja coder?” This was combined with a raffle, which as anyone who has ever been to a conference knows, is the most common tool used to get people to hand over their contact information. To enter, one had simply to look over some Perl code written out on that same poster board and tell them what it did. It looked a little something like this:

my $code = qq{
    print 1+1 . "\n";
    $code =~ m/(\d+)\+(\d+)/;
    $new = $1 + $2;
    $code =~ s/\d+\+(\d+)/$2+$new/;
};

for ( 1 .. 10 ) {
    eval($code);
}

Do you see the bug? It’s actually besides the point, but it’s there.

Yes, it should use q{}, or the variables will interpolate on the initial assignment to $code. To the credit of those staffing the booth, when I pointed this out they responded that the original version used single quotes, but people told them it was too hard to read.

I wasn’t content with just figuring out what the code did and fixing a small bug. I think the code itself can be improved upon. So I hacked something up between sessions:

eval($code = q{
    print 1+1 . "\n";
    $code =~ s/(\d+)(\+)(\d+)/"$3$2" . ($1 + $3)/e;
    eval $code;
});

Much better. Not only is it more concise, I was able to remove that pesky loop, so I wouldn’t be bothered by any silly upper bounds. Except for, you know, overflows and stuff. What’s more, it’s given me something to scare interview candidates with.

5 Comments

Yeah, that is a pretty interesting way to write that :-)

You should be writing Modern Perl!

use 5.010;
eval($code = q{
    say 1+1;
    $code =~ s/(\d+)(\+)(\d+)/"$3$2" . ($1 + $3)/e;
    eval $code;
});

It breaks down on the 89th iteration, btw, which I checked and found is when the result exceeds 61 bits. Perl also starts outputting scientific notation at that point, and three iterations later the output becomes entirely nonsensical.

Sticking a “use bigint;” in there fixes the output format but the results are still worthless. Apparently the parser hits its precision limit for literals at that point.

Technically two bugs: the s/// replacement also has one. (Or perhaps that was a typo in transferring?)

"Write a Perl script to print the first 10 numbers of the Fibonacci sequence" is one of our standard interview questions - not had anybody write it like this yet ;-)

Leave a comment

About Chris Grau

user-pic I use Perl to support an EDA engineering organization. Occasionally I write about the things I do with Perl.