tel2 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I've recently seen this kind of code written by an experience Perler.

perl -ne 'print if s/.*?(?=abc)//...0' inputfile

I think I understand all of it, except the "...0" part.

The code runs without syntax error, and if I change the "...0" to "....0" or "..0" or ".0" or "" (i.e. remove it), then it seems to give the same output.

What is this "...0" about and why is it that changing it to "....0", "..0", ".0" and "" give the same output?

Thanks.

Replies are listed 'Best First'.
Re: What's the "...0" mean?
by jakeease (Friar) on Oct 15, 2010 at 00:08 UTC

    The .. and ... operators test for a start and end pattern. The 2 dot version tests both patterns on the same line once it finds the first one. The 3 dot version doesn't look for the end pattern until the line after finding the start.

    I've used it like this to extract some part of a logfile:

    open my $fh, '<', $log_file or croak "Couldn't open '$log_file'"; while (<$fh>) { push( @session, $_ ) if (/^\d\d\/\d\d\/\d\d.+Start of Logging$ +/m ... /^\d\d\/\d\d\/\d\d.+End of Logging$/m) }
Re: What's the "...0" mean?
by ikegami (Patriarch) on Oct 15, 2010 at 03:22 UTC

    why is it that changing it to "....0", "..0", ".0" and "" give the same output?

    s///.0 -> s/// . 0 s///..0 -> s/// .. 0 s///...0 -> s/// ... 0 s///...0 -> s/// ... .0 -> s/// ... 0

    The last two are identical, save for the use of different literals for zero.

    The .. and ... operators are related, and behave the same given their arguments.

    The . operator (concatenation) does not behave like the range operator.

    >type file 123 abc def >perl -ne"print if s/.*?(?=abc)//.0" file abc >perl -ne"print if s/.*?(?=abc)//..0" file abc def
Re: What's the "...0" mean?
by LanX (Saint) on Oct 15, 2010 at 02:39 UTC
    its called "flip-flop" operator and is effectively a range operator in scalar context.

    A simple number like 0 as operand is compared against the current line number processed.

    Cheers Rolf

Re: What's the "...0" mean?
by locked_user sundialsvc4 (Abbot) on Oct 15, 2010 at 14:27 UTC

    To the simple ways of this simple monk, the range operator (in a scalar context) is a “trick tool” that I tend to avoid, because I know that I can accomplish the same thing just as well with a little more typing (I’m a very good, fast typist...).   Furthermore, I know that I will still be able to understand my own code a few months from now.

    As far as I have been told, the range-operator implementation was done this way, more-or-less to mimic the behavior of another Unix command-line tool.   But when a language feature demands that I “count the number of periods,” my polite response is, “no, I’d rather not, thank you.”

    The anonymous writer on developertutorials.com put it well when (s)he said, “Personally, I’ll usually write out a much longer loop maintaining my own flip-flops than use this, just because I often get tricked by its nuances.   If your brain works better than mine, you might find these handy in quite a few situations.”

    What I would do, given this situation, is to first very-carefully determine what this little block of code is doing, and then rewrite it in some other way.   But, I am but a simple monk...

Re: What's the "...0" mean?
by tel2 (Pilgrim) on Oct 15, 2010 at 04:08 UTC

    Thanks for that, guys.

    However, I'm still not clear on the practicalities of this in the context of my example.

    If the input file is:

    zabcz zzabczz zzzabczzz

    And I run the one-liner:

    perl -ne 'print if s/.*?(?=abc)//...0' <infile

    I get this output:

    abcz zzabczz zzzabczzz

    If I change it to "...1", I get the *same* output. Why?

    If I change it to "...2", I get this output:

    zabcz zzabczz abczzz

    What's going on?

      If .. or ... in used scalar context, and one of the arguments is a numerical literal (as is the case here), there's an implicit comparison against $. is made. So, in the given examples, after matching the left hand side of ..., $. equals 1. So, before the right hand side is tested, $. equals 2. Hence, ...0 or ...1 will never match, but ...2 will.

        Thanks JavaFan (brave name for a Perl forum),

        > Hence, ...0 or ...1 will never match, but ...2 will.

        But "...0" and "...1" seem to have matched the 1st line of the input file, where they changed "zabcz" to "abcz", right?

        Why did they both match the 1st line, but "...2" matched the 3rd line?

Re: What's the "...0" mean?
by tel2 (Pilgrim) on Oct 17, 2010 at 21:09 UTC
    Thanks to you all for your help with this.
    tel2