Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^2: Precompiling qr/.../o question

by mr_mischief (Monsignor)
on Apr 02, 2008 at 15:28 UTC ( [id://677981]=note: print w/replies, xml ) Need Help??


in reply to Re: Precompiling qr/.../o question
in thread Precompiling qr/.../o question

Are you sure?

for ( 1 .. 5 ) { $foo = qr/$_/o; print "Match!\n" if '1' =~ m/$foo/; }

and

for ( 1 .. 5 ) { $foo = qr/$_/; print "Match!\n" if '1' =~ m/$foo/; }

print entirely different outputs on perl 5.8.8 for me.

Further, the reference in perlop for qr lists this usage:

qr/STRING/msixpo

The 'o' is listed as meaning "Compile pattern only once.".

perlop does go on to say that if the compiled regex is embedded in a larger pattern that 'o', unlike the other options, will not propagate out to the other parts of the regex.

Replies are listed 'Best First'.
Re^3: Precompiling qr/.../o question
by hardburn (Abbot) on Apr 02, 2008 at 19:11 UTC

    Sure, it technically works (probably because /o gets dragged along into qr// like any other regex option list), but it's still redundant and confusing.

    The problem with /o is when you start with something harmless like this:

    for (1 .. 5) { print "Match!\n" if $some_string =~ /very long regex/o; }

    Then later you realize you need to add a loop variable to the regex:

    for (1 .. 5) { print "Match!\n" if $some_string =~ /very long regex $_ more regex/o; }

    Which results in the regex checking against '1' instead of the current loop var. This is almost never what you want, and has caused new and experienced programmers alike to waste many hours of debugging. That's why qr// was invented to Do the Right Thing.


    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      Your wording read to me like you meant that the /o option was semantically redundant when used on the qr// itself.

      Now I realize you meant something else entirely. I think you're saying that as a feature it's been made redundant because there are better ways to accomplish that it was originally meant to do. I wouldn't disagree with that.

Re^3: Precompiling qr/.../o question
by ack (Deacon) on Apr 04, 2008 at 17:21 UTC

    In your two additional examples (where you put $_ into the regex's) you are defeating the purpose of the 'compiled' regex. The compile option, I thought, was specifically for cases where the regex itself does *not* change.

    I thought the advantage of using the qr() construct was so that the compiler would look at the regex and do the right thing...i.e., compile the regex once if it does not change, otherwise recompile every usage when it *does* change. I'm not sure what the compiler does when you tell it to compile a regex (using the /o option specifier) that is not essentially static...in fact, I vaguely recall reading that it results in unpredictable regex compiler behavior. Is that the cause of the ...different behavior... that is reported in this thread? My recollection of the compiler behavior may just be a bad memory...since I usually work hard to ensure that the regex is really static and can safely expect to compile it only onc.

    I don't consider myself to be more than a novice with regex's...I'm gaining more and more experience with them and starting to drift towards that dangerous mental construct of seeing every problem as a regex waiting to birth itself. So all of the other good advice and commentary is from much more accomplished and knowledgable monks.

    ack Albuquerque, NM
      Your question is one of scope, I think. Setting $foo to a compiled regex once per loop, then using it in many matches and/or substitutions later in the loop is one thing. Setting it to not recompile even when otherwise told to do so is another. We could discuss at great length the merits and faults with having those two options, but precompiling the regex once per loop iteration for a loop with two dozen matches using that regex I think still makes sense.

        I didn't realize that the compiler was re-invoked after every loop. I thought the compilation takes place before the entire script is executed (or, I guess more correctly, I should say 'interpreted'). I didn't realize that the decision to compile the regex is done on every pass through the loop.

        Certainly, with the regex compilation decision being invoked on every pass throught the loop, I would absolutely agree that it makes sense to, as you said "...precompiling the regex once per loop iteration for a loop with two dozen matches using that regex I think still makes sense...". That would, as you noted, be much more efficient than having to re-compile on every instance of regex throughout the loop...especially if you had many instances in the loop of using that regex.

        Thanks. I really appreciate your helping me dig deeper into and learn more about the magic of regex's.

        ack Albuquerque, NM

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2024-03-28 22:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found