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.
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:if ($left .. $right) { ... }
This program prints out the second and third line of the data. A numeric value in the scalar range operator is therefore compared to $..while (<DATA>) { print if 2 .. 4; } __DATA__ first second third fourth fifth __OUTPUT__ second third fourth
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.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
while (<DATA>) { print if 2 .. /end/; } __DATA__ first second third end ignore __OUTPUT__ second third end
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
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
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.while (<DATA>) { if (my $num = /start/ ... /end/) { print "$num\t$_"; } } __DATA__ ignore start first end ignore __OUTPUT__ 1 start first end 2 ignore
Update: Changed examples to not include so many edge cases. Thanks to hossman.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: The Scalar Range Operator
by pg (Canon) on Jul 27, 2004 at 05:41 UTC | |
Re: The Scalar Range Operator
by hossman (Prior) on Jul 27, 2004 at 01:53 UTC | |
Re: The Scalar Range Operator
by denishowe (Acolyte) on Sep 11, 2012 at 13:43 UTC | |
Re: The Scalar Range Operator
by PipTigger (Hermit) on May 31, 2016 at 15:32 UTC | |
Re: The Scalar Range Operator
by Fengor (Pilgrim) on Nov 28, 2006 at 11:30 UTC |