Global bug of the day: Test::Builder

Ovid on 2008-02-26T11:49:38

Today I upgraded to the latest stable Test::Builder and now we have the following failure:

#!/usr/bin/env perl

use strict;
use warnings;

use Test::Builder 0.75;
use Test::More qw/no_plan/;
BEGIN {
    package Foo;
    use Test::More;
}

TODO: {
    local $TODO = 'foobar';
    ok 0, 'testing todo';
}

Since my latest posts have been focusing heavily on global effects breaking code, you might be immediately suspicious of the local $TODO and you'd be right.

Test::Builder versions 0.75 and above have an ok() method which has this interesting line:

my $todo = $self->todo;

It used to say this:

my($pack, $file, $line) = $self->caller;

my $todo = $self->todo($pack);

In the todo method, we have this:

sub todo {
    my($self, $pack) = @_;

    $pack = $pack || $self->exported_to || $self->caller($Level);
    return 0 unless $pack;

    no strict 'refs';   ## no critic
    return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'}
                                     : 0;
}

In other words, rather than check our actual calling package, we wind up checking the last package that the functions were exported to.

Once again, relying on global data has introduced a bug in our code.

This bug has been reported.