tags:

views:

219

answers:

3

The docs for qr/STRING/ say:

This operator quotes (and possibly compiles) its STRING as a regular expression.

What worries me is the part in parentheses. I can't think of any cases where I don't want it to compile a regex out of STRING. Is this parenthetical statement just weasel words to cover some future case where compiling is not desired or is there a case today (or in an earlier version of Perl) where STRING will not be compiled?

+1  A: 

If the regex contains any interpolated strings, it always compiles (maybe not if you use the /o switch - I confess /o has always confused me). If the regex contains only literal text, I believe Adam's answer is correct.

IIRC it's meant to handle this scenario:

while (my $foo = $something->next) {
     my $regex1 = qr/ab(cd+)ef?/; # only compiled once
     my $regex2 = qr/ab${foo}*ef/; # compiled every time through the loop
     # do stuff with $regex1 and $regex2
}
Dan
If this is what it means then it is phrased very badly.
Chas. Owens
+1  A: 

Edit: This answer is wrong (or at least misguided) but there's some interesting discussion in the comments that's worth preserving. John Siracusa's answer appears to be on the right track.


The documentation for qr// states that

STRING is interpolated the same way as PATTERN in m/PATTERN/.

which presumably includes the behavior of not recompiling regular expressions for which the pattern hasn't changed, or can't change in the case of not including interpolated variables. For example, you don't need to recompile this pattern on each iteration of the loop:

foreach my $char ('a' .. 'z') {
    my $vowel = qr/[aeiou]/;
    say "$char is a vowel" if $char =~ $vowel;
}
Michael Carman
What does that have to do with the section I quoted? The fact that Perl is caching the compile doesn't mean `$vowel` won't be handed a quoted and compiled version of `STRING`. The phrase I am asking about seems to say it is possible for `qr/STRING/` to return a quoted, but not compiled, version of `STRING`. I am asking if there is any case currently or in the past where `qr/STRING/` does not return a compiled regex. If there is no case where it does, then I should probably submit a patch to clarify that statement.
Chas. Owens
The qr operator compiles its contents into a regex every time it's encountered. (It does this regardless of the presence of an /o modifier.) Hoisting the $vowel = qr/[aeiou]/ line above the loop roughly doubles the execution speed of you example on my system.
John Siracusa
@John Siracusa There does seem to be a cache though, examine this code: http://gist.github.com/247337 If it recompiled every time, then runtime of `diff` and `same` would be the same, but `same` is about three times faster. I think the time difference you are seeing is the time it takes to create the `$vowel` variable and assign the cached, compiled regex to it.
Chas. Owens
Adding a dummy creation and assignment to $vowel still leaves the hoisted version ~190% faster in my testing. I'm sure there's some internal caching in the implementation of qr//, but it seems to be dwarfed by the overhead of actually invoking the qr// operator, which happens every time.
John Siracusa
@Chas Owens: I understand your question now. I think that you're interpreting the quoted section too literally and that the intent was to express that the pattern might not be recompiled rather than that it might not be compiled at all. On the other hand a little later perlop says *...Perl may compile the pattern at the moment of execution of the qr() operator...*. The (very weasel word) "may" implies that the compilation could be either immediate or delayed until the qr// quoted string is used. I agree that a doc patch is in order assuming that we can figure out what it should say.
Michael Carman
@John Siracusa: qr// respects the /o modifier. It might still do... something... but it doesn't re-interpolate the pattern and doesn't (from what I can tell via `use re 'debug'`) recompile it either.
Michael Carman
+7  A: 

The "possibly compiles" part of the documentation probably refers to situations like the one shown below, where the argument to qr// is an already-compiled regex:

use re 'debug';

$re1 = qr/foo/;
$re2 = qr/$re1/;

Running that program shows only one regex being compiled.

Regardless of the intent of that passage, sly allusions to internals details does not clear documentation make. I think a doc patch would be beneficial.

John Siracusa
Bingo! Running this with `use re 'debug'` confirms it.
innaM