Sunday, May 23, 2004

What a difference one sentence makes.

I spent a while on Friday trying to debug a confusing problem with one of my database infrastructure services, written in Perl . It was supposed to do certain tasks only every so often, but one particular thing was happening every loop regardless of what its frequency was set to. After a while, it was narrowed down to something similar to this:

foreach my $sid (@sids) {
    {
        local $Frequency{$name}=&GetSidConfig($sid,$name);
        next unless &CheckTime($name,$DBOffset{$sid});
    }
    #rest of the loop actually doing something
}


Basically looping through databases and using a (potentially) different frequency for each of them.

Now, I've written lots of things similar to this, with the extra block scope to restrict the effects of the local declaration. Eventually it became clear that the 'next' wasn't working as you would normally expect. So I looked in my handy-dandy Perl in a Nutshell reference book to see what it had to say about 'next':

The next command is like the continue statement in C; it starts the next iteration of the loop. Note that if there were a continue block on the above, it would get executed even on discarded lines. If the LABEL is omitted, the command refers to the innermost enclosing loop.

That is all well and good, but it seemed obviously the innermost enclosing loop is the foreach. So why wasn't it skipping the rest of the loop? I spent a while checking out whether the local was working correctly (i.e. that GetSidConfig was returning the right value for each database), and that CheckTime was working as expected (i.e. that DBOffset had been properly initialized for each database).

Everything appeared to be working correctly, and on a whim I checked the next documentation on perldoc. Starting with perl 5.6.1 the 'next' documentation was updated to include this extra sentence:

Note that a block by itself is semantically identical to a loop that executes once. Thus next will exit such a block early.

Well, it sure would have been nice to have that in my book, so I wouldn't have spent all that time debugging the wrong branch of code.

No comments: