Você pode começar com o meu livro Learning Perl . É mais fácil do que adivinhar o que fazer até você acertar (macacos, máquinas de escrever e Hamlet, e tudo mais). :)
brian d foy
Respostas:
285
No Perl, o seguinte é avaliado como falso em condicionais:
0'0'undef''# Empty scalar()# Empty list('')
O resto é verdade. Não há palavras de barra para trueou false.
@BlueWaldo: você também pode usar cmp e <=> ao comparar e atribuir os resultados da comparação a um escalar. $ var = $ var1 cmp $ var2; 'cmp' e '<=>' (usado para comparações numéricas) retornam -1, 0 ou 1 se o argumento esquerdo for menor que, igual a ou maior que o argumento correto. Não é booleano, mas às vezes você pode querer saber se um argumento é igual ou menor que ou maior que o outro, em vez de apenas igual ou não.
user118435
9
Problema 1: Uma lista vazia não é falsa, pois é impossível verificar se uma lista é verdadeira ou falsa. Uma lista vazia no contexto escalar retorna undef.
Ikegami 13/04
4
Problema 2: ('')e ''tem o mesmo valor. Eu acho que você queria sugerir uma lista com um elemento que consiste em uma string vazia (embora parens não crie listas), mas como eu já mencionei, é impossível verificar se uma lista é verdadeira ou falsa.
Ikegami 13/04
6
Problema 3: Objetos com um operador booleano sobrecarregado também podem ser falsos.
Ikegami 13/04
15
@ eternicode, Perl tem dois valores específicos que ele usa quando precisa retornar true e false, então não apenas possui booleanos, mas também true ( !0aka PL_sv_yes) e false ( !1aka PL_sv_no). Ou você está dizendo que o Perl deve coaxar sempre que algo além desses dois valores é testado quanto à veracidade? Isso seria completamente horrível. por exemplo, impediria$x ||= $default;
ikegami
71
A definição mais completa e concisa de false que eu me deparei é:
Qualquer coisa que seja string como string vazia ou string 0é falsa. Tudo o resto é verdade.
Portanto, os seguintes valores são falsos:
A cadeia vazia
Valor numérico zero
Um valor indefinido
Um objeto com um operador booleano sobrecarregado que avalia uma das opções acima.
Uma variável mágica avaliada como uma das opções acima ao buscar.
Lembre-se de que um literal de lista vazia é avaliado como um valor indefinido no contexto escalar; portanto, é avaliado como algo falso.
Uma nota sobre "zeros verdadeiros"
Enquanto os números que strings 0são falsos, os strings que zero são zero não são necessariamente. As únicas strings falsas são 0e a string vazia. Qualquer outra string, mesmo que numere como zero, é verdadeira.
A seguir, são seqüências de caracteres verdadeiras como booleanas e zero como número:
Sem aviso:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Com um aviso:
Qualquer sequência para a qual Scalar::Util::looks_like_numberretorna false. (por exemplo "abc")
se eu entendi direito, a palavra true em Embora os números que se caracterizam como 0 sejam verdadeiros deve ser falsa ou (para evitar confusão) ser avaliada como falsa .
user907860
1
Sua definição "concisa" é inconsistente com sua explicação mais longa. Considere o seguinte: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Agora, $valueserá definido como "XXX", mas será boolificado como falso.
214146 (
1
@ tobyink, a versão concisa não é perfeita, apenas a melhor que encontrei. É para ser prático, não abrangente. Observe que o valor retornado pelo seu boolrealmente é string 0. Além disso, você é desencorajado de criar sobrecargas inconsistentes e os valores retornados podem ser considerados como tais. (por exemplo, um &&pode ser otimizado em um ||, por isso, se estes eram inconsistentes, você teria um problema.)
Ikegami
Não tenho certeza se 0x00é coberto aqui.
Zaid
@Zaid, você quer dizer o valor retornado pelo código 0x00(o valor numérico zero) ou a string 0x00(para a qual looks_like_numberé falso)? De qualquer forma, já está coberto.
Ikegami #
59
O Perl não tem um tipo booleano nativo, mas você pode usar a comparação de números inteiros ou seqüências de caracteres para obter o mesmo comportamento. O exemplo de Alan é uma boa maneira de fazer isso usando comparação de números inteiros. Aqui está um exemplo
my $boolean =0;if( $boolean ){print"$boolean evaluates to true\n";} else {print"$boolean evaluates to false\n";}
Uma coisa que eu fiz em alguns dos meus programas é adicionar o mesmo comportamento usando uma constante:
As linhas marcadas em "use constant" definem uma constante chamada true que sempre é avaliada como 1 e uma constante chamada false que sempre é avaliada por 0. Devido à maneira como as constantes são definidas no Perl, as seguintes linhas de código também falham:
true =0;
true = false;
A mensagem de erro deve dizer algo como "Não é possível modificar constante na atribuição escalar".
Vi isso em um dos comentários que você perguntou sobre a comparação de strings. Você deve saber que, como o Perl combina sequências e tipos numéricos em variáveis escalares, você tem uma sintaxe diferente para comparar sequências e números:
my $var1 ="5.0";my $var2 ="5";print"using operator eq\n";if( $var1 eq $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}print"using operator ==\n";if( $var1 == $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}
A diferença entre esses operadores é uma fonte muito comum de confusão no Perl.
Usar constantes como um pobre equipa as macros dessa maneira é perigoso. Esses exemplos de código não são equivalentes: if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }, o que pode não ser óbvio para um observador casual. (E sim, o último exemplo é um estilo de programação ruim, mas isso não vem ao caso).
Zano
16
Eu recomendo use boolean;. Você precisa instalar o módulo booleano do cpan.
No Perl, como na vida, há muitas verdades. Os inexperientes gostam de escrever coisas bobas if ($my_true_value == true). Fingir que existe Uma Verdade Verdadeira é, na minha experiência, um caminho para a dor e um código ineficiente.
usar o seguinte comando
2
Perl é filosófico por natureza
ILMostro_7
13
Meus favoritos sempre foram
use constant FALSE =>1==0;use constant TRUE => not FALSE;
que é completamente independente da representação interna.
Má resposta, mas uma fonte forte e respeitável em perlmonks.org. Seria bom ter um conteúdo real em vez de um comentário e um link. : - /
ILMostro_7
0
use o seguinte prefixo de arquivo, isso adicionará ao seu script perl eTRUE e eFALSE; na verdade, será REAL (!) verdadeiro e falso (como java)
#!/usr/bin/perluse strict;use warnings;use constant {#real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
eTRUE => bless(do{\(my $o =1)},'JSON::PP::Boolean'),
eFALSE => bless(do{\(my $o =0)},'JSON::PP::Boolean')};
Na verdade, existem algumas razões pelas quais você deve usar isso.
Meu motivo é que, trabalhando com JSON, tenho 0 e 1 como valores para as chaves, mas esse hack garantirá que os valores corretos sejam mantidos ao longo do seu script.
Respostas:
No Perl, o seguinte é avaliado como falso em condicionais:
O resto é verdade. Não há palavras de barra para
true
oufalse
.fonte
undef
.('')
e''
tem o mesmo valor. Eu acho que você queria sugerir uma lista com um elemento que consiste em uma string vazia (embora parens não crie listas), mas como eu já mencionei, é impossível verificar se uma lista é verdadeira ou falsa.!0
akaPL_sv_yes
) e false (!1
akaPL_sv_no
). Ou você está dizendo que o Perl deve coaxar sempre que algo além desses dois valores é testado quanto à veracidade? Isso seria completamente horrível. por exemplo, impediria$x ||= $default;
A definição mais completa e concisa de false que eu me deparei é:
Portanto, os seguintes valores são falsos:
Lembre-se de que um literal de lista vazia é avaliado como um valor indefinido no contexto escalar; portanto, é avaliado como algo falso.
Uma nota sobre "zeros verdadeiros"
Enquanto os números que strings
0
são falsos, os strings que zero são zero não são necessariamente. As únicas strings falsas são0
e a string vazia. Qualquer outra string, mesmo que numere como zero, é verdadeira.A seguir, são seqüências de caracteres verdadeiras como booleanas e zero como número:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Scalar::Util::looks_like_number
retorna false. (por exemplo"abc"
)fonte
my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };
. Agora,$value
será definido como "XXX", mas será boolificado como falso.bool
realmente é string0
. Além disso, você é desencorajado de criar sobrecargas inconsistentes e os valores retornados podem ser considerados como tais. (por exemplo, um&&
pode ser otimizado em um||
, por isso, se estes eram inconsistentes, você teria um problema.)0x00
é coberto aqui.0x00
(o valor numérico zero) ou a string0x00
(para a quallooks_like_number
é falso)? De qualquer forma, já está coberto.O Perl não tem um tipo booleano nativo, mas você pode usar a comparação de números inteiros ou seqüências de caracteres para obter o mesmo comportamento. O exemplo de Alan é uma boa maneira de fazer isso usando comparação de números inteiros. Aqui está um exemplo
Uma coisa que eu fiz em alguns dos meus programas é adicionar o mesmo comportamento usando uma constante:
As linhas marcadas em "use constant" definem uma constante chamada true que sempre é avaliada como 1 e uma constante chamada false que sempre é avaliada por 0. Devido à maneira como as constantes são definidas no Perl, as seguintes linhas de código também falham:
A mensagem de erro deve dizer algo como "Não é possível modificar constante na atribuição escalar".
Vi isso em um dos comentários que você perguntou sobre a comparação de strings. Você deve saber que, como o Perl combina sequências e tipos numéricos em variáveis escalares, você tem uma sintaxe diferente para comparar sequências e números:
A diferença entre esses operadores é uma fonte muito comum de confusão no Perl.
fonte
use warnings;
em vez de#! perl -w
if ($exitstatus) { exit; }
vsif ($exitstatus == true) { exit; }
, o que pode não ser óbvio para um observador casual. (E sim, o último exemplo é um estilo de programação ruim, mas isso não vem ao caso).Eu recomendo
use boolean;
. Você precisa instalar o módulo booleano do cpan.fonte
if ($my_true_value == true)
. Fingir que existe Uma Verdade Verdadeira é, na minha experiência, um caminho para a dor e um código ineficiente.Meus favoritos sempre foram
que é completamente independente da representação interna.
fonte
Me deparei com um tutorial que tem uma boa explicação sobre quais valores são verdadeiros e falsos no Perl . Afirma que:
Os seguintes valores escalares são considerados falsos:
undef
- o valor indefinido0
o número 0, mesmo se você o escrever como 000 ou 0,0''
a string vazia.'0'
a sequência que contém um único dígito 0.Todos os outros valores escalares, incluindo o seguinte, são verdadeiros:
1
qualquer número diferente de 0' '
a corda com um espaço nela'00'
dois ou mais 0 caracteres em uma sequência"0\n"
um 0 seguido por uma nova linha'true'
'false'
sim, até a string 'false' é avaliada como true.Há outro bom tutorial que explica sobre Perl verdadeiro e falso .
fonte
Linda explicação dada por bobf para valores booleanos: Verdadeiro ou Falso? Um Guia de Referência Rápida
Testes de verdade para diferentes valores
fonte
use o seguinte prefixo de arquivo, isso adicionará ao seu script perl eTRUE e eFALSE; na verdade, será REAL (!) verdadeiro e falso (como java)
Na verdade, existem algumas razões pelas quais você deve usar isso.
Meu motivo é que, trabalhando com JSON, tenho 0 e 1 como valores para as chaves, mas esse hack garantirá que os valores corretos sejam mantidos ao longo do seu script.
fonte