Hi,

I'm seeing strange behaviour when the pattern for a s/// is an empty string and I was wondering if someone could explain why this behaviour occurs? (man pages are fine too!) Thanks.

If I use an empty pattern for a substitute op on its own, then no values are replaced. For example:

use strict; use warnings; my $msg = 'this is a test'; my $pat = ''; my $rep = ''; $msg =~ s/$pat/$rep/; print $msg, "\n";

Running this gives me what I expect:

this is a test

However, it seems that if I use a substitute prior to this substitute then it uses the pattern of the first operator - even if it acts on a different variable. For example:

use strict; use warnings; my $c = 'this is another test'; $c =~ s/^this is/XX/; my $msg = 'this is a test'; my $pat = ''; my $rep = ''; $msg =~ s/$pat/$rep/; print $msg, "\n";

Then the output becomes:

a test

As far as I can see the empty pattern causes the substitution operator to use the previous pattern, almost as though it is caching it. It only uses the pattern too, the value is not re-used, and further it seems that it only occurs if the substitution is successful. A failed match doesn't trigger this.

This is rather surprising behaviour, and quiet alarming too. I discovered this because one of my customers reported a problem with an application we produce. I narrowed it down to this, but I haven't been able to find any description about this activity. My assumption would be that it would either does nothing, because it's looking for a 0-width string and fails to find it, or that it applies to every part of the string because it is a 0-width pattern which matches between every character in the string (sort of like a \b). That it reuses an old pattern, and a pattern applied to a totally separate variable, is very odd behaviour. I'm not sure if this is considered "undefined behaviour", but it makes me concerned for any code that I've written where the substitution pattern comes from a scalar rather than being hard coded.

Any suggestions on why this is happening (or where it is defined that this happens) are greatly appreciated. I'm using:

perl -v This is perl, v5.8.8 built for x86_64-linux-thread-multi-ld

On an Fedore Core 6 x86 2x dual core opteron box with Perl compiled from source against standard FC6 RPM libraries

Thanks, Colin.


In reply to s/// with an empty pattern uses the previous pattern of a s/// by ckeith100

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.