Na seção anterior do Tutorial Perl introduzimos as variáveis escalares e vimos como números e strings são instantaneamente convertidos um no outro. Vimos brevemente sobre a condicional if mas não vimos como comparar escalares. É disto que trata esta parte.
Dadas duas variáveis $x e $y, como podemos compara-las? Serão 1, 1.0 e 1.00 iguais? O que dizer sobre "1.00"? O que é maior: "foo" ou "bar"?
Dois conjuntos de operadores de comparação
O Perl possui dois conjuntos de operadores de comparação. Como vimos com os operadores binários de adição (+), concatenação (.) e repetição (x), aqui também o operador é o responsável por definir como os operandos se comportarão e de que forma eles serão comparados.
Os dois conjuntos de operadores são os seguintes:
Numérico String Significando
== eq igual
!= ne diferente
< lt menor que
> gt maior que
<= le menor ou igual a
>= ge maior ou igual a
Os operadores à esquerda compararão os valores como números enquanto os operadores à direita (a coluna do meio) vão comparar os valores baseados na tabela ASCII ou com base nas configurações locais de linguagem do sistema (locale).
Vejamos alguns exemplos:
use strict;
use warnings;
use 5.010;
if ( 12.0 == 12 ) {
say "TRUE";
} else {
say "FALSE";
}
Neste caso simples o Perl vai imprimir TRUE pois o operador ==
compara os dois números e o Perl não se preocupa se o número está escrito como um
inteiro ou como número em notação de ponto flutuante.
Uma situação mais interessante seria comparar
"12.0" == 12
que também é TRUE pois o operador ==
converte a string em um número.
2 < 3 é TRUE porque < compara os dois números.
2 lt 3 também é TRUE pois 2 antecede 3 na tabela ASCII.
12 > 3 é obviamente TRUE.
12 gt 3 retorna FALSE.
Isto pode surpreender algumas pessoas no início, mas se você pensar um pouco, a forma como o Perl compara duas strings é letra por letra. Então "1" é comparado com "3" e como eles são diferentes e "1" aparece antes de "3" na tabela ASCII, o Perl decide neste ponto que a string 12 é menor que a string 3.
Você deve se certificar que está comparando as coisas como você realmente quer!
"foo" == "bar" será TRUE
Isto também lhe dará dois alertas (warnings) se(!) você habilitou os alertas
através do use warnings;
. A razão para o alerta é que você está usando
duas strings como se fossem números na comparação numérica == e isto é o que gera os
alertas. Como mencionado anteriormente, o Perl vai olhar o lado esquerdo de
cada string e converte-las nos números que ele encontrar. Como as duas strings
começam com uma letra, ambas serão transformadas em 0.
0 == 0 e por isto temos TRUE.
OTOH (On The Other Hand - por outro lado):
"foo" eq "bar" retorna FALSE
Então você tem que ter certeza de comparar os valores como você os quer!
O mesmo acontece quando você compara
"foo" == "" retorna TRUE
e
"foo" eq "" retorna FALSE
Esta tabela pode ser útil para ver os resultados:
12.0 == 12 TRUE
"12.0" == 12 TRUE
"12.0" eq 12 FALSE
2 < 3 TRUE
2 lt 3 TRUE
12 > 3 TRUE
12 gt 3 FALSE ! (cuidado, pode não ser óbvio a primeira vista)
"foo" == "" TRUE ! (Você recebe alertas se usar o pragma "warnings")
"foo" eq "" FALSE
"foo" == "bar" TRUE ! (Você recebe alertas se usar o pragma "warnings")
"foo" eq "bar" FALSE
Por fim, um exemplo onde as pessoas podem cair em uma armadilha é quando se recebe alguma entrada do usuário e depois de remover cuidadosamente a quebra de linha do final da entrada, tenta-se verificar se a string dada é vazia.
use strict;
use warnings;
use 5.010;
print "input: ";
my $name = <STDIN>;
chomp $name;
if ( $name == "" ) { # errado! aqui você precisa usar eq ao invés de == !
say "TRUE";
} else {
say "FALSE";
}
Se você rodar este script e digitar "abc" você vai receber TRUE como retorno, como se o Perl pensasse que "abc" é igual à string vazia.