Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Why qr// needs /o modifier, or bug in a documentation.

Reply
Thread Tools

Why qr// needs /o modifier, or bug in a documentation.

 
 
ddtl
Guest
Posts: n/a
 
      09-02-2003

Hello everybody,

I have some difficulty to understand why does qr// operator needs
'o' modifier. There seems to be a disagreement between perlop manpage
and "Programming Perl" (3rd edition - i will use PP for short from now
on).

From PP (chapter 5.9.2.2), it is clear that qr// needed for the cases
when it is impossible to use usual /o modifier, and a programmer wants
to spare recompilation every time RE is evaluated. Here is a quote:

-----------------------------------------------------------------------
Variables that interpolate into patterns necessarily do so at run time,
not compile time. This slows down execution because Perl has to check
whether you've changed the contents of the variable; if so, it would
have to recompile the regular expression. As mentioned in
"Pattern-Matching Operators", if you promise never to change the pattern,
you can use the /o option to interpolate and compile only once:

print if /$pattern/o;

Although that works fine in our pgrep program, in the general case,
it doesn't. Imagine you have a slew of patterns, and you want to match
each of them in a loop, perhaps like this:

foreach $item (@data) {
foreach $pat (@patterns) {
if ($item =~ /$pat/) { ... }
}
}

You couldn't write /$pat/o because the meaning of $pat varies each time
through the inner loop.

The solution to this is the qr/PATTERN/imosx operator. This operator
quotes--and compiles--its PATTERN as a regular expression. PATTERN is
interpolated the same way as in m/PATTERN/. If ' is used as the delimiter,
no interpolation of variables (or the six translation escapes) is done.
The operator returns a Perl value that may be used instead of the equivalent
literal in a corresponding pattern match or substitute.
-----------------------------------------------------------------------

But perlop manpage says something different:


-----------------------------------------------------------------------
qr/STRING/imosx

This operator quotes (and possibly compiles) its STRING as a regular
expression. STRING is interpolated the same way as PATTERN in m/PATTERN/.
If "'" is used as the delimiter, no interpolation is done. Returns a
Perl value which may be used instead of the corresponding /STRING/imosx
expression.
-----------------------------------------------------------------------

According to the manpage, it is quite common that qr// does not compile
RE, which is, except being different from the said in the book, doesn't
really make sense - why would otherwise anybody will need qr// for?

Also, the book doesn't even mention an existence of /o modifier for
qr// when he talks about modifiers (in the same section. though it
does mention it in the previous quote):

-----------------------------------------------------------------------
....
....
The reason this works is because the qr// operator returns a special kind
of object that has a stringification overload as described in Chapter 13,
"Overloading". If you print out the return value, you'll see the equivalent
string:

$re = qr/my.STRING/is;
print $re; # prints (?si-xm:my.STRING)

The /s and /i modifiers were enabled in the pattern because they were
supplied to qr//. The /x and /m, however, are disabled because they were not.
-----------------------------------------------------------------------



Additionally, using "use re "debug";" option, i checked what is the
difference between when you add /o modifier to qr// and when you don't -
and as i found out - there is no difference, the expression was compiled
only once when compiler reached qr// operator (while it was compiled every
time RE was evaluated when a usual double-quoted string was used.
Here is my test case:

---------------------------------------
#!/usr/bin/perl
use strict;
use re "debug";

my $re = qr/world/;
"hello world" =~ /$re/;
"hello world" =~ /$re/;
---------------------------------------


The output i get when running the program (which is the same regardless of
/o modifier)



---------------------------------------
Compiling REx `world'
size 4 Got 36 bytes for offset annotations.
first at 1
1: EXACT <world>(4)
4: END(0)
anchored `world' at 0 (checking anchored isall) minlen 5
Offsets: [4]
1[5] 0[0] 0[0] 6[0]
Guessing start of match, REx `world' against `hello world'...
Found anchored substr `world' at offset 6...
Starting position does not contradict /^/m...
Guessed: match at offset 6
Guessing start of match, REx `world' against `hello world'...
Found anchored substr `world' at offset 6...
Starting position does not contradict /^/m...
Guessed: match at offset 6
Freeing REx: `"world"'
---------------------------------------




Is there is an error in the manpage? If it is not, how it is possible to
explain the difference between the book and the manpage, and especially -
why there is a need for qr// according to the manpage's version?


ddtl.


 
Reply With Quote
 
 
 
 
Anno Siegel
Guest
Posts: n/a
 
      09-03-2003
ddtl <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>
> Hello everybody,
>
> I have some difficulty to understand why does qr// operator needs
> 'o' modifier. There seems to be a disagreement between perlop manpage
> and "Programming Perl" (3rd edition - i will use PP for short from now
> on).


The qr// operator doesn't need the /o modifier, you must have misunder-
stood what the documentation is saying. The relation is that qr// can
be used to achieve what /o would be needed for without it.

[snip]

Anno
 
Reply With Quote
 
 
 
 
ddtl
Guest
Posts: n/a
 
      09-03-2003

>The qr// operator doesn't need the /o modifier, you must have misunder-
>stood what the documentation is saying. The relation is that qr// can
>be used to achieve what /o would be needed for without it.


Maybe i have chosen rather wrong wording. qr// certainly does not
*need* the /o operator in a sense that it is syntactically correct to
write a statement containing qr// operator without writing an /o
modifier, but if you don't add /o modifier, RE will be compiled every
time it is evaluated, that is what manpage says.

First of all, operator's signature is (everything between double
quotes is quoted from perlop manpage):

"qr/STRING/imosx"

that is, obviously there *is* /o modifier for qr//.

"Options are:

i Do case-insensitive pattern matching.
m Treat string as multiple lines.
o Compile pattern only once.
s Treat string as single line.
x Use extended regular expressions.
"

As the quote above says, if you use /o, pattern is compiled only once,
which obviously means that if you don't use /o - pattern would be
compiled more then once, which is exactly what happens when instead of
using 'qr//'ed expression you use a plain variable in m// or s//.


So, obviously qr// operator *does* need the /o modifier in order to
be equivalent to the usual RE with /o modifier, which means that the
question is still valid.

Maybe you have another explanation to the above quotes from the manpage?
For the time being i don't see any other way to understand it...


ddtl.
 
Reply With Quote
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      09-03-2003
On 3 Sep 2003, Anno Siegel wrote:

>ddtl <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>>
>> Hello everybody,
>>
>> I have some difficulty to understand why does qr// operator needs
>> 'o' modifier. There seems to be a disagreement between perlop manpage
>> and "Programming Perl" (3rd edition - i will use PP for short from now
>> on).

>
>The qr// operator doesn't need the /o modifier, you must have misunder-
>stood what the documentation is saying. The relation is that qr// can
>be used to achieve what /o would be needed for without it.


But the qr// operator can take the /o modifier. Perhaps it's a super rare
condition, but you can use it.

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
Sam Holden
Guest
Posts: n/a
 
      09-03-2003
On Wed, 03 Sep 2003 18:52:18 +0400, ddtl <(E-Mail Removed)> wrote:
>
>>The qr// operator doesn't need the /o modifier, you must have misunder-
>>stood what the documentation is saying. The relation is that qr// can
>>be used to achieve what /o would be needed for without it.

>
> Maybe i have chosen rather wrong wording. qr// certainly does not
> *need* the /o operator in a sense that it is syntactically correct to
> write a statement containing qr// operator without writing an /o
> modifier, but if you don't add /o modifier, RE will be compiled every
> time it is evaluated, that is what manpage says.


The manpage does not say that. In fact the manpage says almost the opposite:

Since Perl may compile the pattern at the moment of execution of qr()
operator, using qr() may have speed advantages in some situations,
notably if the result of qr() is used standalone:

[snip example that doesn't use /o]

Precompilation of the pattern into an internal representation at the
moment of qr() avoids a need to recompile the pattern every time a
match "/$pat/" is attempted.

- perldoc perlop



> First of all, operator's signature is (everything between double
> quotes is quoted from perlop manpage):
>
> "qr/STRING/imosx"
>
> that is, obviously there *is* /o modifier for qr//.
>
> "Options are:
>
> i Do case-insensitive pattern matching.
> m Treat string as multiple lines.
> o Compile pattern only once.
> s Treat string as single line.
> x Use extended regular expressions.
> "
>
> As the quote above says, if you use /o, pattern is compiled only once,
> which obviously means that if you don't use /o - pattern would be
> compiled more then once, which is exactly what happens when instead of
> using 'qr//'ed expression you use a plain variable in m// or s//.


Just because A -> B, does not mean that !A -> !B.

Just because the pattern is compiled once with /o, does not mean that
the pattern is not compiled once without /o.

>
> So, obviously qr// operator *does* need the /o modifier in order to
> be equivalent to the usual RE with /o modifier, which means that the
> question is still valid.
>
> Maybe you have another explanation to the above quotes from the manpage?
> For the time being i don't see any other way to understand it...


The o on qr//o doesn't do anything, since qr// precompiles already.

For example:

$needle = 'foo';
$re = qr/$needle/;
$reo = qr/$needle/o;

sub check {
print "\$needle = $needle\n";
for (@_) {
print ' /$needle/ matches ',"$_\n" if /$needle/;
print ' /$needle/o matches ',"$_\n" if /$needle/o;
print ' /$re/ matches ', "$_\n" if /$re/;
print ' /$reo/ matches ', "$_\n" if /$reo/;
}
}


check('barbaz');
$needle = 'bar';
check('barbaz');

Obviously qr// *does not* need the /o modifier in order to be
equivalent to the usual RE with the /o modifier, as evidenced
by the fact that /$needle/o, /$re/, and /$reo/ all fail to match
'barbaz' even though $needle is set to 'bar' in the above code.

--
Sam Holden

 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      09-03-2003
ddtl <(E-Mail Removed)> wrote in comp.lang.perl.misc:
>
> >The qr// operator doesn't need the /o modifier, you must have misunder-
> >stood what the documentation is saying. The relation is that qr// can
> >be used to achieve what /o would be needed for without it.

>
> Maybe i have chosen rather wrong wording. qr// certainly does not
> *need* the /o operator in a sense that it is syntactically correct to
> write a statement containing qr// operator without writing an /o
> modifier, but if you don't add /o modifier, RE will be compiled every
> time it is evaluated, that is what manpage says.
>
> First of all, operator's signature is (everything between double
> quotes is quoted from perlop manpage):
>
> "qr/STRING/imosx"
>
> that is, obviously there *is* /o modifier for qr//.
>
> "Options are:
>
> i Do case-insensitive pattern matching.
> m Treat string as multiple lines.
> o Compile pattern only once.
> s Treat string as single line.
> x Use extended regular expressions.
> "
>
> As the quote above says, if you use /o, pattern is compiled only once,
> which obviously means that if you don't use /o - pattern would be
> compiled more then once, which is exactly what happens when instead of
> using 'qr//'ed expression you use a plain variable in m// or s//.
>
>
> So, obviously qr// operator *does* need the /o modifier in order to
> be equivalent to the usual RE with /o modifier, which means that the
> question is still valid.


Your question seems to be: If qr// is supposed to be used when /o can't
be (because the pattern changes occasionally), why is it allowed to
recompile each time (without /o).

The answer is, you are not supposed to just replace /.../o by qr/.../
literally. qr// allows you to compile a regex in one place, and apply
it in another. So you recompile (using qr//) when needed, and replace
the /.../o with a variable that holds the value where you want to apply
the regex.

Look again at the examples, which you quoted in your first post. They
make pretty clear how qr// is supposed to solve the //o problem.

> Maybe you have another explanation to the above quotes from the manpage?
> For the time being i don't see any other way to understand it...


You have made a wrong assumption: That qr// goes where the regex used to be.

Anno
 
Reply With Quote
 
Jeff 'japhy' Pinyan
Guest
Posts: n/a
 
      09-04-2003
[posted & mailed]

On 3 Sep 2003, Sam Holden wrote:

> $needle = 'foo';
> $re = qr/$needle/;
> $reo = qr/$needle/o;


This is a bad example. These lines are only RUN once.

Compare:

sub make_qr {
my $pat = shift;
return qr/$pat/o;
}

print make_qr('foo'), "\n";
print make_qr('bar'), "\n";

It prints the foo regex both times.

--
Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
"And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

 
Reply With Quote
 
Sam Holden
Guest
Posts: n/a
 
      09-04-2003
On Wed, 3 Sep 2003 22:22:47 -0400, Jeff 'japhy' Pinyan <(E-Mail Removed)> wrote:
> [posted & mailed]
>
> On 3 Sep 2003, Sam Holden wrote:
>
>> $needle = 'foo';
>> $re = qr/$needle/;
>> $reo = qr/$needle/o;

>
> This is a bad example. These lines are only RUN once.


I thought the post I was replying to was refering to that case...

Of course, I'm often wrong.

--
Sam Holden

 
Reply With Quote
 
ddtl
Guest
Posts: n/a
 
      09-04-2003

>Your question seems to be: If qr// is supposed to be used when /o can't
>be (because the pattern changes occasionally), why is it allowed to
>recompile each time (without /o).
>
>The answer is, you are not supposed to just replace /.../o by qr/.../
>literally. qr// allows you to compile a regex in one place, and apply
>it in another. So you recompile (using qr//) when needed, and replace
>the /.../o with a variable that holds the value where you want to apply
>the regex.


But that does not explain why /o is needed! Yes, qr// allows you to
compile a regex in one place, and apply it in another, because if
it wasn't possible your RE would be recompiled every time it is evaluated,
and we want to be able to compile RE only once, so we use qr//. But
if we use qr// with /o, RE would be compiled every time RE is evaluated,
which defeats the whole reason for usage of qr//o.

Maybe you could give an example when it makes difference between
using qr//o and plain quoted string, that is, between:

-----------------
my $re = qr/hello/o;
....
....
/$re/;
....
....
/$re/;
-----------------

and:

-----------------
my $re = /hello/;
....
....
/$re/;
....
....
/$re/;
-----------------

According to the manpage, whenever "/$re/;" is evaluated, RE would be
recompiled in both examples, so why would i use qr//o at all - exactly
the same thing happens when qr//o is not used!

That is without the fact that in the first example RE actually compiled
only once (when "my $re = qr/hello/o;" is being evaluated - and there is
no difference whether you use /o or not - which means that /o does not
has *any* effect on compilation of RE, which is not what documentation says),
while in the second example RE compiled every time it is evaluated (that is,
every time "/$re/;" executed), though according to the manpage qr//o
is supposed to be recompiled every time RE is evaluated.


>Look again at the examples, which you quoted in your first post. They
>make pretty clear how qr// is supposed to solve the //o problem.


It is clear to me what problem qr// is supposed to solve, it is not
clear why

1) would somebody use /o modifier,

and

2) what is the difference between using qr// and qr//o - according
to the messages from debugger there is none at all and /o modifier does
not has any effect (try running an examples with "use re "debug";").


ddtl.
 
Reply With Quote
 
ddtl
Guest
Posts: n/a
 
      09-04-2003
>Just because A -> B, does not mean that !A -> !B.
>
>Just because the pattern is compiled once with /o, does not mean that
>the pattern is not compiled once without /o.


So what that means? Do you mean that when it is said:

"o Compile pattern only once."

means that when you *do not* use 'o', pattern is also compiled only
once?? If A -> B does not mean that !A -> !B (and what you want to say
is that when !A there is still B), means that A is not the only reason
for B. If so, why do you need A at all - it is surely not because
you want B, because B exists even without A. And that is just rephrasing
of my question *why* do you need /o???

ddtl.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
*bug* *bug* *bug* David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM
why why why why why Mr. SweatyFinger ASP .Net 4 12-21-2006 01:15 PM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
BUG! needs to click button twice to show the summary info! Jos ASP .Net 3 11-15-2004 08:34 PM
OO Bug needs squashing nick Python 3 04-13-2004 12:57 AM



Advertisments