How should I use Perl's scalar range operator?
What is the scalar ".." operator typical usage? Is it only selecting blocks of text?
Interesting example by myself:
sub get_next {
print scalar($$..!$$), "\n";
}
get_next for 1 .. 5; # prints numbers from 1 to 5
get_next for 1 .. 5; # prints numbers from 开发者_运维问答6 to 10
People hardly seem to know about it based on questions here, but, yes, I'd say typical usage is selecting blocks of text, either with
while (<>) {
print if /BEGIN/ .. /END/;
}
or
while (<>) {
print if 3 .. 5; # prints lines 3 through 5
}
The latter is syntactic sugar for checking against the input line-number ($.
)
... if $. == 3 .. $. == 5;
which suggests the weird-looking
#! /usr/bin/perl -l
for ($_ = 1; $_ <= 10; ++$_) {
print if $_ == 4 .. $_ == 7;
}
The above program's output is
4 5 6 7
If you have some sort of bracketing condition, test for it in subs:
for (...) {
do_foo($x,$y,$z) if begin($x) .. end($z);
}
Outside of perl -e
you really shouldn't. It is esoteric and funky. See my post not even 24hrs ago about it about how it maintains state with calling context. This stung me in a real world application, because I was trying to be clever and found what I thought was a good use-case for it.
Here's a place where you need to be very careful about unintentional use of the scalar range operator: subroutine returns.
sub range {
my $start = shift;
my $end = shift;
return $start .. $end;
}
@foo = range( 1, 5 ); # ( 1, 2, 3, 4, 5 )
$foo = range( 1, 5 ); # False or maybe true. Who knows.
If you call this subroutine in scalar context, you'll be in for a surprise.
After being bitten by some variant of this problem, I now always make sure I assign a list return into an array, thereby getting array-like context behaviors for my subs. If I need other context specific behavior (very rarely) I use wantarray
.
sub range {
my $start = shift;
my $end = shift;
my @result = $start .. $end;
return @result;
}
another use is simple counters like this:
perl -e 'foreach ( 1 .. 100 ){print"$_\n"}'
精彩评论