### Comment on

 Need Help??

## The Scalar Range Operator

I have been playing with the scalar range operator, and it confused me so much that I started experimenting and reading about it, and here is what I wrote up.

### Numeric Values

This operator, in scalar context, has two forms that act as a bistable or flip-flop. The first form looks like this:
```  if (\$left .. \$right)
{
...
}
This if statement works as follows: The condition evaluates false until \$left evaluates true. Then the \$left condition is ignored, and the condition continues to evaluate true until \$right evaluates true, at which point the condition evaluates false, and it goes back to check \$left. In this way, it flip-flops between waiting for the left side to evaluate true, and then waiting for the right side to evaluate true. Very strange, until you see it operating in a program:
```  while (<DATA>)
{
print if 2 .. 4;
}

__DATA__
first
second
third
fourth
fifth

__OUTPUT__
second
third
fourth
This program prints out the second and third line of the data. A numeric value in the scalar range operator is therefore compared to \$..

### Regular Expressions

This example shows the use of two regular expressions in the scalar range operator:
```  while (<DATA>)
{
print if /start/ .. /end/;
}

__DATA__
ignore
start
first
second
third
end
ignore
start
fourth
fifth
end
ignore

__OUTPUT__
start
first
second
third
end
start
fourth
fifth
end
It prints out lines in the data beginning with the line that first evaluates true (start), until the line that next evaluates true (end). All the lines that are not bracked by start/end pairs are ignored. Note that this data contains two blocks of lines that are between start and end markers, and the lines outside those ranges are ignored.

### Numeric and Regular Expressions

Combining a numeric and a regex in the range operator also works as expected. In this example, the lines from \$. == 1 until \$_ =~ /end/ are printed.
```  while (<DATA>)
{
print if 2 .. /end/;
}

__DATA__
first
second
third
end
ignore

__OUTPUT__
second
third
end

### Exluding Markers

In order to exclude lines that contain start and end, a further condition is required. The condition is that the result returned by the scalar range operator must be neither 1 (representing \$. of 1), nor must it contain E. When the operator encounters the line that evaluates true for the right-hand-side, it's return value is (in the example below) 5E0. This number evaluates to 5, but contains that E, which is the indicator that this line terminates the right-hand-side of the operator. This code prints all the lines between the start and end lines:
```  while (<DATA>)
{
if (my \$num = /start/ .. /end/)
{
print unless \$num == 1 || \$num =~ /E/;
}
}

__DATA__
ignore
start
first
second
third
end
ignore
start
fourth
fifth
end
ignore

__OUTPUT__
first
second
third
fourth
fifth

To better illustrate that, this program prints out that value, for all lines between start and end:

```  while (<DATA>)
{
if (my \$num = /start/ .. /end/)
{
print \$num, "\t", \$_;
}
}

__DATA__
ignore
start
first
second
third
end
ignore
start
fourth
fifth
end
ignore

__OUTPUT__
1       start
2       first
3       second
4       third
5E0     end
1       start
2       fourth
3       fifth
4E0     end

### Markers on Same Line

This example places both the start and end tokens on the same line. From the output, it can be seen that the combined line has a value of 1E0 which satisfies the test as both the first and last line of the desired input.
```  while (<DATA>)
{
if (my \$num = /start/ .. /end/)
{
print \$num, "\t", \$_;
}
}

__DATA__
ignore
start
first
second
end
ignore
start third end
ignore

__OUTPUT__
1       start
2       first
3       second
4E0     end
1E0     start third end

### The Scalar ... Operator

The other form of the scalar range operator is .... This operator performs as the .. operator does, but lines that meet one criteria are not also evaluated for the other. So a line that contains both start and end is only evaluated once - in this case for the start line, causing this data to be considered as having a start but not an end, meaning that the data is not properly treated in this example.
```  while (<DATA>)
{
if (my \$num = /start/ ... /end/)
{
print "\$num\t\$_";
}
}

__DATA__
ignore
start first end
ignore

__OUTPUT__
1       start first end
2       ignore
This form of the scalar range operator is more efficient only if it is known that both conditions can never be true on the same line.

Update: Changed examples to not include so many edge cases. Thanks to hossman.

In reply to The Scalar Range Operator by pbeckingham

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.
• Posts may use any of the Perl Monks Approved HTML tags:
a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, 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, 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: & & < < > > [ [ ] ]
• Link using PerlMonks shortcuts! What shortcuts can I use for linking?

Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2018-07-23 16:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

Results (472 votes). Check out past polls.

Notices?