Como devo usar o operador de intervalo escalar do Perl?
Pergunta
Qual é o uso típico do operador escalar ".."?É apenas selecionar blocos de texto?
Exemplo interessante por mim mesmo:
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
Solução
As pessoas dificilmente parecem saber sobre isso com base em perguntas aqui, mas sim, eu diria que o uso típico está selecionando blocos de texto, seja com
while (<>) {
print if /BEGIN/ .. /END/;
}
ou
while (<>) {
print if 3 .. 5; # prints lines 3 through 5
}
O último é o açúcar sintático para verificar o número da linha de entrada ($.
)
... if $. == 3 .. $. == 5;
o que sugere a aparência estranha
#! /usr/bin/perl -l
for ($_ = 1; $_ <= 10; ++$_) {
print if $_ == 4 .. $_ == 7;
}
A saída do programa acima é
4 5 6 7
Se você tiver algum tipo de condição de entrega, teste -o em Subs:
for (...) {
do_foo($x,$y,$z) if begin($x) .. end($z);
}
Outras dicas
Fora de perl -e
você realmente não deveria.É esotérico e descolado.Veja minha postagem há menos de 24 horas sobre isso como ele mantém o estado com o contexto de chamada.Isso me machucou em um aplicativo do mundo real, porque eu estava tentando ser inteligente e descobri o que achei ser um bom caso de uso para isso.
Aqui está um lugar onde você precisa ter muito cuidado com o uso não intencional do operador da faixa escalar: Retornos da sub -rotina.
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.
Se você chamar essa sub -rotina no contexto escalar, você terá uma surpresa.
Depois de ser mordido por alguma variante desse problema, agora sempre garanto que atribua uma lista de retorno a uma matriz, obtendo comportamentos de contexto semelhantes a matrizes para meus subs. Se eu precisar de outro comportamento específico do contexto (muito raramente), eu uso wantarray
.
sub range {
my $start = shift;
my $end = shift;
my @result = $start .. $end;
return @result;
}
Outro uso são contadores simples como este:perl -e 'foreach ( 1 .. 100 ){print"$_\n"}'