Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^3: Turning on regexp debugging at runtime

by SBECK (Chaplain)
on Sep 23, 2014 at 16:15 UTC ( [id://1101675]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Turning on regexp debugging at runtime
in thread Turning on regexp debugging at runtime

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).

Replies are listed 'Best First'.
Re^4: Turning on regexp debugging at runtime
by Anonymous Monk on Sep 23, 2014 at 16:29 UTC

    The name DEBUG_REGEX is made up, and can be anything (note the test of $ENV{DEBUG_REGEX} in the code).

    How about:

    my $re1 = qr/a/; my $re2 = do { use if $ENV{FOO_DEBUG_REGEX}, qw/re Debug EXECUTE/; qr/b/ }; my $re3 = qr/c/; my $str = "ab"; $str =~ $re1; $str =~ $re2; $str =~ $re3;

    will output run-time debug info on $re2 only when the environment var FOO_DEBUG_REGEX is set.

    I'm not sure if this can be done dynamically in the debugger, perhaps another monk with more experience there can help. The documentation does say that use re 'debug'; has both compile-time and run-time effects.

      Thanks. I misunderstood DEBUG_REGEX.

      Unfortunately, the actual situation is very complicated. There are literally hundreds of regexps, and I'd like to be able to debug any one of them at any time. Also, they are called multiple times, so I might only be interested in the 4th time that a regexp is called.

      Unfortunately, the "use regexp" pragma is applied when the regexp is created... I want something to turn debugging on when a regexp is matched against.

      It's really not that big of a deal... I can workaround it by simply ignoring a lot of unwanted output. I was just hoping for something a little cleaner during debugging time.

        This technique was completely new to me as well, but judging from the example code it looks like you can test for pretty much any condition you like if an environment variable doesn't suit your needs.

        -- FloydATC

        Time flies when you don't know what you're doing

        Try this:

        { use re debug; my $re = qr/myregex/; } ... if ($item =~ /$re/) { ... }

        Update: SBECK had said:

        Unfortunately, the "use regexp" pragma is applied when the regexp is created... I want something to turn debugging on when a regexp is matched against.

        so I tried to make a helpful suggestion.

        Sorry it was not helpful

Re^4: Turning on regexp debugging at runtime
by Monk::Thomas (Friar) on Sep 24, 2014 at 14:00 UTC
    Hello

    Are you aware you can scope more easily using

    $str = "abc"; $re1 = qr/a/; $re2 = qr/b/; { use re 'debug'; $str =~ $re1; } $str =~ $re2;
    However since the whole process does not seem to help you anyway: Can you please provide more code? It doesn't seem very useful to match like crazy but not doing anything with the match results.

      Your example doesn't work. The re pragma (as far as I can tell) does something when the regexp is created, so if I run your code, nothing is output.

      However, even if it was, this really doesn't do what I want. Imagine the following code:

      $re1 = qr/.../; $re2 = qr/.../; ... $reN = qr/.../; @str = ('some','list','of','strings'); foreach my $str (@str) { $str =~ /$re1/; $str =~ /$re2/; ... $str =~ /$reN/; }

      That's basically the situation that I have. But I don't want to turn on debugging for all regexps, or even for a single regexp every time it is used. What I want is to be able to debug $re2 when applied to the 5th string and nothing else.

      The way I want this to work is that I run this program in the debugger, step through until I get to the particular regexp match that I want to debug, and then I type "use re 'debug'" and I'm ready to go.

      Unfortunately, it doesn't work. The regexp was already created without debugging turned on, so (as far as I can tell), there is no way to turn it on for this one particular match.

      Anyway, as I said, it's far from the end of the world... I can turn on debugging and then run the script to the point i'm interested in and ignore all the unwanted debug output from all the other times the regexp was matched. This is mainly a convenience question.

        SBECK:

        In that case, go ahead and recompile the regex in the debugger, like this:

        do { use re qw(Debug More); $re1=qr/g/; }

        We simply create a block and inside it, we turn on regex debug mode, and compile the regex.

        Here's the test run I did:

        $ cat t.pl use strict; use warnings; my $re1 = qr/p/; my $re2 = qr/t/; use re qw(Debug More); my @list = ('alpha', 'beta', 'gamma', 'delta'); for (@list) { print $_, "\n"; if (/$re1/) { print "has P\n" } if (/$re2/) { print "has T\n" } } $ perl -d t.pl <<< snip >>> main::(t.pl:4): my $re1 = qr/p/; DB<1> s main::(t.pl:5): my $re2 = qr/t/; DB<1> main::(t.pl:9): my @list = ('alpha', 'beta', 'gamma', 'delta'); DB<1> main::(t.pl:11): for (@list) { DB<1> main::(t.pl:12): print $_, "\n"; DB<1> alpha main::(t.pl:13): if (/$re1/) { print "has P\n" } DB<1> main::(t.pl:13): if (/$re1/) { print "has P\n" } DB<1> has P main::(t.pl:14): if (/$re2/) { print "has T\n" } DB<1> p { use re qw(Debug More); $re1=qr/g/; } Compiling REx "g" Final program: 1: EXACT <g> (3) 3: END (0) anchored "g" at 0 (checking anchored isall) minlen 1 DB<2> s main::(t.pl:12): print $_, "\n"; DB<2> beta main::(t.pl:13): if (/$re1/) { print "has P\n" } DB<2> Guessing start of match in sv for REx "g" against "beta" Did not find anchored substr "g"... Match rejected by optimizer main::(t.pl:14): if (/$re2/) { print "has T\n" } DB<2> main::(t.pl:14): if (/$re2/) { print "has T\n" } DB<2> has T main::(t.pl:12): print $_, "\n"; DB<2>

        If you want to switch back and forth, then you may want another variable that you can use to hold the original (nondebug) version, so you can copy it back after you're done with the debug version.

        Note: As you can see, I originally intended to leave regex debugging on by doing so after compiling all the regexes. But it seems that it was optimized out, so that's why I had to wrap it during debugging. It may be easy to leave the regex engine in debug mode so you can avoid the do { } block, but once I had something that worked, I stopped.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

        Your example doesn't work.

        Uhm. Yes. I was aware of that. I just wanted to highlight that you don't need to 'reset' the lexical scoping by descending into another level if all you have to do is leave the scope.

        What I still don't get is why you are doing all this in the first place. Unless I'm missing something

        foreach my $str (@str) { $str =~ /$re1/; $str =~ /$re2/; ... $str =~ /$reN/; }
        doesn't do anything except wasting some CPU cycles to match strings and throw away the result. Maybe by giving us more information a cleaner solution can be found?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1101675]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-04-24 06:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found