Search code examples
regexperldebuggingperl-module

Regexp::Debugger Perl module doesn't seem to work within another Perl Module


I am writing a Perl module that involves some very complicated regular expressions that are nearly impossible to debug without a tool to help me. I figured the Regexp::Debugger module would be the perfect tool for the job, but it only seems to work in .pl scripts and doesn't seem to work within a .pm module.


For example, this works:

test.pl

use strict;
use warnings;
use Regexp::Debugger;

my $text = "text";
if ($text =~ /tex/) {
    print "Match!";
}

And I get the expected debugging functionality.


But the second I introduce a Perl Module to the mix it no longer works:

test.pl

use strict;
use warnings;
use TestModule;

TestModule::func();

TestModule.pm

package TestModule;

use strict;
use warnings;
use Regexp::Debugger;

sub func {
    my $text = "text";
    if ($text =~ /tex/) {
        print "Match!";
    }
}

1;

Attempting to run this code gives the following error:

Can't use an undefined value as a HASH reference at Regexp/Debugger.pm line 160

Simply including Regexp::Debugger in the "test.pl" file instead doesn't work either because it doesn't try to debug regexes within included modules.

How can I get this to work so I can debug the regexes within a module that I'm working on?


UPDATE:

A bug report has been filed, and a new version (v0.002001) is now available on CPAN that works as expected. :)


Solution

  • This seems to be a bug in the way Regexp::Debugger checks lexical hints in calling scopes, but I'm not sure how to fix it. For reference, https://metacpan.org/source/DCONWAY/Regexp-Debugger-0.002000/lib/Regexp/Debugger.pm#L160 is:

    my $lexical_scope = (caller 1)[10]{'Regexp::Debugger::lexical_scope'};
    

    Maybe it should do ((caller 1)[10] || {})->{'Regexp::Debugger::lexical_scope'} instead?


    Anyway, I was able to reproduce your problem and I found a workaround. In test.pl, do:

    use strict;
    use warnings;
    no Regexp::Debugger;
    use TestModule;
    

    I.e. load Regexp::Debugger before you use TestModule, but with no instead of use to avoid activating it for the main program.

    With this change, I get:

    TestModule.pm did not return a true value at test.pl line 4.
    BEGIN failed--compilation aborted at test.pl line 4.
    

    ... which is still an error, but it's a good error. It means there were no problems with Regexp::Debugger.

    If I then add a line of 1 at the end of TestModule.pm, everything works.


    Update: OP reported the problem and it was fixed in version 0.002001 of Regexp::Debugger.