Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Turning on regexp debugging at runtime

by SBECK (Chaplain)
on Sep 23, 2014 at 14:55 UTC ( #1101654=perlquestion: print w/replies, xml ) Need Help??

SBECK has asked for the wisdom of the Perl Monks concerning the following question:

When tracking down a tricky regexp related problem, it's nice to turn on regexp debugging:

use re 'debug';

Ideally, I would like to be able to toggle it on and off (especially in the debugger) because there may be a lot of other regexp matching going on that works perfectly well, and I want to get to the portion that is broken. Unfortunately, I haven't figured out how to do that.

I know this comes down to me not truly understanding how pragmas work, and maybe it's not possible, but is there a way to toggle debugging during runtime?

Replies are listed 'Best First'.
Re: Turning on regexp debugging at runtime
by Anonymous Monk on Sep 23, 2014 at 15:12 UTC

    As of 5.9.5 the directive use re 'debug'; is lexically scoped, so you can do something like:

    my $re1 = qr/foo|bar/; { use re 'debug'; my $re2 = qr/quz|baz/; { no re 'debug'; my $re3 = qr/hello|world/; } }

    And you'll only get debugging info for the scope where the directive is on.

    See 'debug' in re and the pages it links to for more details. As you can see in that documentation, you can also use use re qw(Debug EXECUTE); to get only the debug output related to the run-time phase.

      As for easily turning debugging on and off, here's one way via environment vars:

      my $re1 = qr/foo|bar/; { use if $ENV{DEBUG_REGEX}, qw/re Debug EXECUTE/; my $re2 = qr/quz|baz/; print "xfoox"=~$re1, "ybazy"=~$re2; }

      gives you run-time debug info on $re2 only when the environment var DEBUG_REGEX is set.

        Thanks for both of these replies, especially the second since I wasn't aware of the DEBUG_REGEX environment variable.

        I should have been a bit clearer, but it appears that what I want to do probably can't be done. For example, say I have the absurdly simple script:

        $re1 = qr/a/; $re2 = qr/b/; $re3 = qr/c/; $str = "ab"; $str =~ $re1; $str =~ $re2; $str =~ $re3;

        what I want to do is step through the code (in the debugger) and turn on debugging (by executing "use re 'debug'") when I match against $re2 but then turn it back off before proceeding to the $re3 match.

        I could put each in it's own scope, but that would be messy (I don't really want to put every regexp in it's own scope so that I could potentially debug it individually).

        Even worse is that the regexps in question were built outside of the scope, so I actually end up with something more similar to this:

        $str = "abc"; $re1 = qr/a/; $re2 = qr/b/; { use re 'debug'; $str =~ $re1; { no re 'debug'; $str =~ $re2; } }

        which won't print any debugging info at all.

        Oh well, I can do what I've always done (temporarily enable debugging and then go to the point in the code I'm interested in ignoring all the unwanted debugging output).

Re: Turning on regexp debugging at runtime
by LanX (Cardinal) on Sep 24, 2014 at 14:22 UTC
    IMHO it should be possible at the debugger prompt to manually eval a line with use re 'debug' enabled,

    This could be automatized with an alias command to be manually invoked, to take the next (or last) line to be executed to be debugged.

    My quick testing couldn't make it work, either because

    • my Perl version is too old for use re 'debug'
    • because re-debugging needs to be enabled at start time and than disabled
    • probably both

    Left as an exercise to interested monks with much time... :)

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

Re: Turning on regexp debugging at runtime
by Anonymous Monk on Sep 25, 2014 at 11:41 UTC

    Out of curiosity I hacked something up for you:

    { my %orig; sub re_db_on (\$) { my ($r) = @_; die "not a regex" unless ref $$r eq 'Regexp'; return if $orig{$r}; $orig{$r} = $$r; # note this depends on the proper stringification of the regex $$r = eval qq{ use re qw/Debug EXECUTE/; qr/$$r/ }; } sub re_db_off (\$) { my ($r) = @_; return unless $orig{$r}; $$r = delete $orig{$r}; } } my $ra = qr/a/; my $rb = qr/b/; my $rc = qr/c/; my $str = "abc"; $,=", "; $\="\n"; print $str=~$ra, $str=~$rb, $str=~$rc; re_db_on $rb; print $str=~$ra, $str=~$rb, $str=~$rc; re_db_off $rb; print $str=~$ra, $str=~$rb, $str=~$rc;

    Tested on v5.20 / Linux. The subs work when called from the debugger too.

      Even though it's noted in the comment in the code, I guess that caveat should be highlighted: This method will probably not work reliably on regular expressions that can't be completely represented by their stringified selves.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1101654]
Approved by ww
Front-paged by LanX
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (2)
As of 2021-04-17 22:55 GMT
Find Nodes?
    Voting Booth?

    No recent polls found