Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
"be consistent"
 
PerlMonks  

difference between qr// and the use of the o modifier ?

by arhuman (Vicar)
on Jan 30, 2001 at 13:30 UTC ( #55214=perlquestion: print w/ replies, xml ) Need Help??
arhuman has asked for the wisdom of the Perl Monks concerning the following question:

What's the difference between:
$re=qr/foo/i; s/$re/bar/;
and
s/foo/bar/io;

Which is fastest ? most efficient/elegant ?
Sorry if my question is stupid, but I didn't find anything in my camel book (2nd edition) about qr

Comment on difference between qr// and the use of the o modifier ?
Select or Download Code
Post 1000, /o vs qr//
by tilly (Archbishop) on Jan 30, 2001 at 14:25 UTC
    The fastest and most efficient in this case is:
    s/foo/bar/i;
    The difference between qr//, using /o, and using no flag is the time of binding variables in your pattern to the RE. If (as in this case) the pattern doesn't involve any variables, perl will recognize that at compile time and you should leave it to the interpreter. However if your pattern involves a variable, there are three basic possibilities.
    1. The safest assumption is that your variable may change at any time, and your pattern will need to be recompiled before each use. That is what you get by default.
    2. The fastest but most dangerous assumption is that your variable is a constant that never will change in the lifetime of your program. That is what /o is for.
    3. In between those two extremes you have cases where the programmer knows that a pattern will be used repeatedly but the variable it depends on may change. The qr// construct (which is explained in your local documentation, try perldoc perlop) is for this case. Here when you call qr// you are telling Perl exactly when to compile the pattern. I typically would do it in functions where I will be matching a pattern many times. I want the speedup, but I don't want to risk having my function work incorrectly if it is called twice.
    In older Perl's (say Camel 2 vintage) there wasn't a qr// operator (introduced in 5.004 IIRC). To get a similar effect people used to use eval to produce an anonymous subroutine that would do the match and had a hard-coded pattern. (By showing a friend how to do this I sped his data-cleaning-and-loading program up by 40%.) I mention this as a historical curiousity only, today you would just use qr// for this problem.

    Note
    This is my 1000'th post. I had thought about issuing some sort of general thank-you, but then I decided that the best kind of thank-you for finding both Perl and this site enjoyable is giving another explanation. If I didn't enjoy it, I wouldn't be here. :-)

      Congratulations tilly! ++ for dedication ;)

      $japh->{'Caillte'} = $me;
      Thank you ! 2 times :
      For your (clear) answer.
      And for your dedication to the perlmonks community.
Re: difference between qr// and the use of the o modifier ?
by Caillte (Friar) on Jan 30, 2001 at 14:45 UTC

    s///o and qr// are pretty much the opposite of each other. If you make a regexp with the o argument you are basicly tellin the compiler that you will not change any of the variables associated with this regexp. Because of this perl will only ever compile this regexp once and will never change it, even if you do change the variables.

    qr// is used to compare a string for use in a regexp. Consider the following:

    $tofind = "some string"; while(<DATA>) { push @list, $_; } # Make a compiled list with qr @clist = map qr/$_/, @list; # Now run the two lists foreach (@list) { print "Found $tofind\n", last if($tofind =~ /$_/); } foreach (@clist) { print "Found $tofind\n", last if($tofind =~ /$_/); }

    Warning: This code was written by a sleepy, coffee deprived programmer first thing in the morning. It has not been tested and may not run, explode and/or set fire to your computer.

    The second loop, with @clist, will run faster as a lot of work has been done for the compiler already. Another possible use is when you have a list of patterns to match and you want to run some against certain rules (say case insensitivity) and some against others. You could either write a complicated set of subroutines or add extra data to flag which pattern had which requirement... or just precompile them all with qr!

    $japh->{'Caillte'} = $me;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://55214]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (10)
As of 2014-04-20 22:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (488 votes), past polls