use 5.016;
use warnings "all";
use Data::Dumper;
my @abc = (1, 2, 3);
my @bbb = @abc[1..2];
my @ccc = @abc[1...2];
my @ddd = @abc[1....2];
say Dumper "@bbb"; # output: '2 3'
say Dumper "@ccc"; # output: '2 3'
say Dumper "@ddd"; # output: ''
Why is there no syntax error in code above?
What do 1...2 (three dots) and 1....2 (four dots) mean here?
0
2 Answers
1..2 is tokenized as 1 .. 2, and parsed as a range operator with two integer constant operands. When evaluated, it is evaluated in list context, and it produces the integers from 1 to 2 inclusive.
1...2 is tokenized as 1 ... 2, and parsed as a range operator with two integer constant operands. ... is different than .. in scalar context, but they’re the same in list context.
1....2 is tokenized as 1 ... .2, and parsed as a range operator with two constant operands. When evaluated, it is evaluated in list context, and it produces the integers from 1 to 0.2 inclusive, which is to say it produces nothing.
A side note:
When tokenizing, Perl normally gobbles up as many characters as it can with no regard as to what follows. One exception is that a . will never be included in a numeric literal if followed by another ..
This means that 1..2 is always tokenized as 1, .., 2 and never 1. .2 or 1. . 2.
This means that 1...2 is always tokenized as 1, ..., 2 and never 1., .., 2 or 1, .., .2.
This also means that 1.....2 will never be tokenized as 1. ... .2 even though that would prevent the parser from throwing a syntax error.
(Thanks @Dada for helping me correct this.)
A side note:
At least some constant ranges are flattened into an array constant.
1..2 in list context and 1...2 in list context both compile to a two-element array constant, just like 1, 2.
1....2 in list context compiles to an empty array constant.
0
If you give Perl the option -MO=Deparse it will say how Perl parse your code.
The three-dot form (1...2) parses as (1..2). This is unexpected to me, but I assume it is a side effect of being able to parse both the two-dot and three-dot forms of the flip-flop operator.
The four-dot form parses as (1 .. .2). This is an empty range, so your array slice is also empty.
1
-
Re "The three-dot form (1…2) parses as (1..2).", No. They are parsed differently, but they compile to the same the thing in this case. Specifically, they compile to a constant array of two elements, just like
1, 2. /// Re "it will say how Perl parse your code.", Deparse is a decompiler. It can help show how Perl understand codes, but it doesn't actually show how code is parsed. That's why1..2,1...2and1, 2all Deparse as1, 2. (They don't Deparse as1..2as you claim.)– ikegami5 hours ago




