Module::ExtractUse 0.29

During the weekend I got a small bug report for Module::ExtractUse: RT83569. Tonight a had a few silent moments, so I reviewed the problem.

The bug

In this file, Test::Pod was not reported. After checking that a simple & plain require Test::Pod worked, I assumed that the problem was caused by some earlier statements. To save on processing time, Module::ExtractUse splits the code it's examining into statements. By using a rather simple regex, namely /;/.

So the problematic statement was:

  $ENV{RELEASE_TESTING}
    ? die ("Failed to load release-testing module requirements: $missing")
    : plan skip_all => "Test needs: $missing"
}

require Test::Pod;

Debugging

To make testing & debugging easier, I added a new test case containing the whole problematic piece of code. After playing around with this for a few minutes it was clear that the problem was caused by the line

  $ENV{RELEASE_TESTING}
    ? die ("Failed to load release-testing module requirements: $missing")

And after a few more debug statements the problem became obvious:

$statement=~s/^(.*?)require/require/s;
    eval {
        my $parser=Module::ExtractUse::Grammar->new();
        $result=$parser->token_require($statement.';');
    };

Everything before 'require' is discarded and the rest of the statement than passed on to the Parse::RecDescent grammar. But the problematic line includes the string 'requirements', which matches 'require'. And the following text:

ements: $missing") : plan skip_all => "Test needs: $missing" } require Test::Pod;

just doesn't pass as a valid argument to require.

The fix

The fix was easy:

$statement=~s/^(.*?)require\b/require/s;

Note the \b (word boundary) after require. requirements now doesn't match, so all that garbage is now discarded, and we only pass require Test::Pod to the Grammar. Which now of course reports the correct value. Yay!

A new & fixed version of Module::ExtractUse (0.29) is already on it's way to CPAN.

PS: Thanks to ribasushi for submitting the bug report.

PPS: Fixing the bug took ~15 minutes. Writing this post nearly double that time :-)