Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters

Empty pattern and /o

 

 

Perl porters RSS feed   Index | Next | Previous | View Threaded


p5p at perl

May 16, 2008, 2:03 PM

Post #1 of 4 (114 views)
Permalink
Empty pattern and /o

While looking at an old bug report I was, at first, confused by the
following code:


#!/usr/bin/perl -l

use strict;
use warnings;

for (0, 1) {
my $re = ($_ == 0 ? "" : "bar");
my $x = "foo";
$x =~ m/o/o;

if ($x =~ /$re/) {
print "$x =~ /$re/";
}
}
__END__
The output of this:
f o =~ //
f o =~ /bar/


The reason for this is:
$re is empty the first time the loops run so the last succesfull
pattern gets used.

That is m/o/o.
The /o modifier is not dropped so for the next iteration the loop
still matches $x against m/o/ (because of the /o-modifier).


Currently in perlop:
If the PATTERN evaluates to the empty string, the last successfully
matched regular expression is used instead. In this case, only the g
and c flags on the empty pattern is honoured - the other flags are
taken from the original pattern. If no match has previously succeeded,
this will (silently) act instead as a genuine empty pattern (which
will always match).


Should the docs be clearer about the empty pattern and the copying of
the /o modifier? (which can be really confusing...)


Also,

Add: use re 'eval' to the code:

#!/usr/bin/perl -l

use strict;
use warnings;

use re 'eval';

for (0, 1) {
my $re = ($_ == 0 ? "" : "bar");
my $x = "foo";
$x =~ m/o/o;

if ($x =~ /$re/) {
print "$x =~ /$re/";
}
}
__END__
Output:
foo =~ //


So how exactly does use re 'eval' influences the regex?



Kind regards,

Bram


demerphq at gmail

May 16, 2008, 2:15 PM

Post #2 of 4 (105 views)
Permalink
Re: Empty pattern and /o [In reply to]

2008/5/16 Bram <p5p[at]perl.wizbit.be>:
>
> While looking at an old bug report I was, at first, confused by the
> following code:
>
>
> #!/usr/bin/perl -l
>
> use strict;
> use warnings;
>
> for (0, 1) {
> my $re = ($_ == 0 ? "" : "bar");
> my $x = "foo";
> $x =~ m/o/o;
>
> if ($x =~ /$re/) {
> print "$x =~ /$re/";
> }
> }
> __END__
> The output of this:
> f o =~ //
> f o =~ /bar/
>
>
> The reason for this is:
> $re is empty the first time the loops run so the last succesfull pattern
> gets used.
>
> That is m/o/o.
> The /o modifier is not dropped so for the next iteration the loop still
> matches $x against m/o/ (because of the /o-modifier).
>
>
> Currently in perlop:
> If the PATTERN evaluates to the empty string, the last successfully matched
> regular expression is used instead. In this case, only the g and c flags on
> the empty pattern is honoured - the other flags are taken from the original
> pattern. If no match has previously succeeded, this will (silently) act
> instead as a genuine empty pattern (which will always match).
>
>
> Should the docs be clearer about the empty pattern and the copying of the /o
> modifier? (which can be really confusing...)
>
>
> Also,
>
> Add: use re 'eval' to the code:
>
> #!/usr/bin/perl -l
>
> use strict;
> use warnings;
>
> use re 'eval';
>
> for (0, 1) {
> my $re = ($_ == 0 ? "" : "bar");
> my $x = "foo";
> $x =~ m/o/o;
>
> if ($x =~ /$re/) {
> print "$x =~ /$re/";
> }
> }
> __END__
> Output:
> foo =~ //
>
>
> So how exactly does use re 'eval' influences the regex?

eeek. no idea.

Both of these features are hard to deal with. It would be nice to
banish them. But i dont think we can. Unfortunately.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"


abigail at abigail

May 16, 2008, 2:28 PM

Post #3 of 4 (101 views)
Permalink
Re: Empty pattern and /o [In reply to]

On Fri, May 16, 2008 at 11:15:08PM +0200, demerphq wrote:
> 2008/5/16 Bram <p5p[at]perl.wizbit.be>:
> >
> > While looking at an old bug report I was, at first, confused by the
> > following code:
> >
> >
> > #!/usr/bin/perl -l
> >
> > use strict;
> > use warnings;
> >
> > for (0, 1) {
> > my $re = ($_ == 0 ? "" : "bar");
> > my $x = "foo";
> > $x =~ m/o/o;
> >
> > if ($x =~ /$re/) {
> > print "$x =~ /$re/";
> > }
> > }
> > __END__
> > The output of this:
> > f o =~ //
> > f o =~ /bar/
> >
> >
> > The reason for this is:
> > $re is empty the first time the loops run so the last succesfull pattern
> > gets used.
> >
> > That is m/o/o.
> > The /o modifier is not dropped so for the next iteration the loop still
> > matches $x against m/o/ (because of the /o-modifier).
> >
> >
> > Currently in perlop:
> > If the PATTERN evaluates to the empty string, the last successfully matched
> > regular expression is used instead. In this case, only the g and c flags on
> > the empty pattern is honoured - the other flags are taken from the original
> > pattern. If no match has previously succeeded, this will (silently) act
> > instead as a genuine empty pattern (which will always match).
> >
> >
> > Should the docs be clearer about the empty pattern and the copying of the /o
> > modifier? (which can be really confusing...)
> >
> >
> > Also,
> >
> > Add: use re 'eval' to the code:
> >
> > #!/usr/bin/perl -l
> >
> > use strict;
> > use warnings;
> >
> > use re 'eval';
> >
> > for (0, 1) {
> > my $re = ($_ == 0 ? "" : "bar");
> > my $x = "foo";
> > $x =~ m/o/o;
> >
> > if ($x =~ /$re/) {
> > print "$x =~ /$re/";
> > }
> > }
> > __END__
> > Output:
> > foo =~ //
> >
> >
> > So how exactly does use re 'eval' influences the regex?
>
> eeek. no idea.
>
> Both of these features are hard to deal with. It would be nice to
> banish them. But i dont think we can. Unfortunately.


We can't banish them in the sense of making them a syntax error.

But we can change the documentation and remove any suggestion that
/o is a good idea. In the more than dozen years I've been answering
Perl questions, I've encountered people using /o many times.

I cannot recall seeing a single useful use of /o. At best, the use
of /o is harmless.

As for //, I hardly ever see it being used on purpose - and of the
cases I see it being used on purpose, most of them are (contrived)
examples of where // could be useful. I do see cases where people
use /$re/, and $re turns out to be empty.

I wonder whether it's useful (assuming it's feasible) to warn in cases

/$var/

is used, and $var equals "".


Abigail


demerphq at gmail

May 16, 2008, 2:54 PM

Post #4 of 4 (101 views)
Permalink
Re: Empty pattern and /o [In reply to]

2008/5/16 Abigail <abigail[at]abigail.be>:
> On Fri, May 16, 2008 at 11:15:08PM +0200, demerphq wrote:
>> 2008/5/16 Bram <p5p[at]perl.wizbit.be>:
...
>> > Should the docs be clearer about the empty pattern and the copying of the /o
>> > modifier? (which can be really confusing...)
>> >
>> >
>> > Also,
>> >
>> > Add: use re 'eval' to the code:
....
>> >
>> >
>> > So how exactly does use re 'eval' influences the regex?
>>
>> eeek. no idea.
>>
>> Both of these features are hard to deal with. It would be nice to
>> banish them. But i dont think we can. Unfortunately.
>
>
> We can't banish them in the sense of making them a syntax error.

No, i was thinking of making /o a true no-op. And making the empty
pattern only apply when the pattern is truly empty. IOW, a pattern
containing a var which was the empty string should NOT trigger the
empty pattern behaviour.

> But we can change the documentation and remove any suggestion that
> /o is a good idea. In the more than dozen years I've been answering
> Perl questions, I've encountered people using /o many times.
>
> I cannot recall seeing a single useful use of /o. At best, the use
> of /o is harmless.

In perl 5.10 /o can be modestly faster than not using it. But i agree,
almost every time it is used it results in pain and suffering for all
concerned.

> As for //, I hardly ever see it being used on purpose - and of the
> cases I see it being used on purpose, most of them are (contrived)
> examples of where // could be useful. I do see cases where people
> use /$re/, and $re turns out to be empty.

Slight disagreement here. Ive used the empty pattern a few times,
sometimes out of laziness, and sometimes because it happens to make
things nicer.

The two examples im thinking of are :

if (m/$some_big_nasty_pattern/ and $1 eq $something) {
s///;
}

and the other is

if (m/$pat1/ or m/$pat2/ or m/$pat3/) {
s///;
}

The important thing to note is that the only time that ive ever used
either is when doing a match and then needing to repeat the match as
part of a s///. The first example is fairly unimportant. Using qr//
you just reuse the pattern. The second is the only good reason for
keeping this behaviour around, but IMO it would be just as
use(ful|less) if it was restricted to a true empty pattern (as in
lexically empty, not containing a var which may represent the empty
string).

>
> I wonder whether it's useful (assuming it's feasible) to warn in cases
>
> /$var/
>
> is used, and $var equals "".

I think we should drop the behaviour for m// and make it warn. The
empty string behavior should only kick in for s///. For /o we can just
no-op it. (Once we fix the reasons why its actually useful in 5.10 --
sigh).

Cheers,
Yves



--
perl -Mre=debug -e "/just|another|perl|hacker/"

Perl porters RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact lists@gossamer-threads.com
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.