Reputation: 5856
Can anybody show with some examples the exact difference between ..
and ...
operator?
From the perlop man page:
If you don't want it to test the right operand until the next evaluation, as in sed, just use three dots ("...") instead of two.
But what exactly this mean? I don't understand the perlop's example:
@lines = (" - Foo",
"01 - Bar",
"1 - Baz",
" - Quux"
);
foreach (@lines) {
if (/0/ .. /1/) {
print "$_\n";
}
}
with ...
will print the Baz
- but why? More precisely, why is Baz
not printed with two dots and only with ...
?
Upvotes: 31
Views: 5074
Reputation: 150573
There's a great article called Dots and Perl, I recommend you read it.
To summarise:
Concatenation operator:
say "one" . "two";
# Outputs "onetwo"
Range operator:
my @numbers = (1..100); # has one hundred numbers from 1 to 100
Flip-flop operator:
while (my $line = readline($fh)) {
process_this_line($line) if m/START/ .. m/END/;
}
Yada-yada statement:
sub example {
...
# throws "Unimplemented" exception when called
}
Flip-flop operator, three-dot version:
while (my $line = readline($fh)) {
process_this_line($line) if m/START/ ... m/END/;
# The only difference between this and the two-dot version
# occurs when a single line has both START and END
}
The other answers go into more detail on the difference between the two flip-flop operators.
Upvotes: 3
Reputation: 385645
«...
» doesn't do a flop check immediately after a true flip check.
With «..
»,
" - Foo"
/0/
returns false...
returns false."01 - Bar"
/0/
returns true. Flip!/1/
returns true. Flop! ⇐..
returns true (since the first check was true)."1 - Baz"
/0/
returns false...
returns false." - Quux"
/0/
returns false...
returns false.With «...
»,
" - Foo"
/0/
returns false....
returns false."01 - Bar"
/0/
returns true. Flip!...
returns true."1 - Baz"
/1/
returns true. Flop!...
returns true." - Quux"
/0/
returns false....
returns false.Upvotes: 18
Reputation: 29595
Repeating the example here:
@lines = (" - Foo",
"01 - Bar",
"1 - Baz",
" - Quux"
);
foreach (@lines) {
if (/0/ .. /1/) {
print "$_\n";
}
}
It's tricky... what's happening when you use the 2 dots ..
is that when you reach "01 - Bar"
, both conditions are tested and both succeed (because that line has a 0
and also a 1
). So your printing is turned on and immediately turned off.
However, when you use ...
, the first condition succeeds, but the second one is not tried until the next iteration of the loop, so "01 - Bar"
turns it on and "1 - Baz"
turns it off. Thus you see both lines printed.
The tricky part is to realize that the "01 - Bar"
satisfies both tests.
Upvotes: 4
Reputation: 3116
If you have cases like /start/ .. /end/
with input
start some text end
start
some other text
end
the ..
operator will process the end
in the first line as soon as it reads it and will only print some text
. The ...
operator will not process the end
on the first line so the other text will also be printed. Basically you can avoid stopping the range if the ending value is matched on the same line as the start. The ...
postpones the check until the next iteration.
Upvotes: 4