Come uso le variabili booleane in Perl?


220

Ho provato:

$var = false;
$var = FALSE;
$var = False;

Nessuno di questi lavori. Ricevo il messaggio di errore

Bareword "false" non consentito mentre è in uso "sottotitoli rigorosi".

37
Potresti voler iniziare con il mio libro Learning Perl . È più facile che indovinare cosa fare fino a quando non lo si ottiene correttamente (scimmie, macchine da scrivere e Amleto e tutto il resto). :)
brian d foy,

Risposte:


285

In Perl, quanto segue valuta falso in condizionali:

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

Il resto è vero. Non ci sono parole in chiaro per trueo false.


2
@BlueWaldo: è inoltre possibile utilizzare cmp e <=> quando si confrontano e assegnano i risultati del confronto a uno scalare. $ var = $ var1 cmp $ var2; 'cmp' e '<=>' (utilizzato per i confronti numerici) restituisce -1, 0 o 1 se l'argomento sinistro è minore, uguale o maggiore dell'argomento destro. Non è booleano ma a volte potresti voler sapere se un argomento è uguale o minore o maggiore dell'altro invece che solo uguale o non uguale.
user118435

9
Problema 1: un elenco vuoto non è falso, poiché è impossibile verificare se un elenco è vero o falso. Viene restituito un elenco vuoto in un contesto scalare undef.
ikegami,

4
Problema 2: ('')e ''hanno lo stesso valore. Penso che tu abbia voluto implicare un elenco con un elemento che consiste in una stringa vuota (anche se i genitori non creano elenchi), ma come ho già detto, è impossibile verificare se un elenco è vero per falso.
ikegami,

6
Problema 3: anche gli oggetti con un operatore booleano sovraccarico possono essere falsi.
ikegami,

15
@eternicode, Perl ha due valori specifici che usa quando deve restituire vero e falso, quindi non solo ha valori booleani, ma ha true ( !0aka PL_sv_yes) e false ( !1aka PL_sv_no). O stai dicendo che Perl dovrebbe gracchiare ogni volta che qualcosa di diverso da questi due valori viene testato per la verità? Sarebbe del tutto terribile. ad esempio, impedirebbe$x ||= $default;
ikegami il

71

La definizione più completa e concisa di falso che ho incontrato è:

Tutto ciò che si stringe nella stringa vuota o nella stringa 0è falso. Tutto il resto è vero.

Pertanto, i seguenti valori sono falsi:

  • La stringa vuota
  • Valore numerico zero
  • Un valore indefinito
  • Un oggetto con un operatore booleano sovraccarico che valuta una delle precedenti.
  • Una variabile magica che valuta uno dei precedenti al momento del recupero.

Tieni presente che un elenco vuoto letterale valuta un valore indefinito in un contesto scalare, quindi valuta qualcosa di falso.


Una nota sugli "zeri reali"

Mentre i numeri che si stringono 0sono falsi, le stringhe che si numerano a zero non lo sono necessariamente. Le uniche stringhe false sono 0e la stringa vuota. Qualsiasi altra stringa, anche se numera a zero, è vera.

Di seguito sono le stringhe che sono vere come un valore booleano e zero come un numero:

  • Senza preavviso:
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • Con un avvertimento:
    • Qualsiasi stringa per la quale Scalar::Util::looks_like_numberrestituisce false. (ad es. "abc")

se ho capito bene la parola vero in Mentre i numeri che si stringono a 0 sono veri dovrebbero essere falsi o (per evitare confusione) valutano come falsi .
user907860,

1
La tua definizione "concisa" non è coerente con la tua spiegazione più lunga. Prendere in considerazione: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Ora $valuesi stringerà su "XXX" ma boolifica su falso.
tobyink

1
@tobyink, La versione sintetica non è perfetta, ma solo la migliore che abbia trovato. È pensato per essere pratico, non onnicomprensivo. boolTieni presente che il valore restituito dal tuo si applica a 0. Inoltre, si è scoraggiati dalla creazione di sovraccarichi incoerenti e i valori restituiti potrebbero essere considerati tali. (es. a &&può essere ottimizzato in a ||, quindi se questi fossero incoerenti, avresti un problema.)
ikegami,

Non sono sicuro se 0x00è coperto qui.
Zaid,

@Zaid, vuoi dire il valore restituito dal codice 0x00(il valore numerico zero) o dalla stringa 0x00(per cui looks_like_numberè falso)? Ad ogni modo, è già coperto.
ikegami,

59

Perl non ha un tipo booleano nativo, ma è possibile utilizzare il confronto di numeri interi o stringhe per ottenere lo stesso comportamento. L'esempio di Alan è un bel modo di farlo usando il confronto di numeri interi. Ecco un esempio

my $boolean = 0;
if ( $boolean ) {
    print "$boolean evaluates to true\n";
} else {
    print "$boolean evaluates to false\n";
}

Una cosa che ho fatto in alcuni dei miei programmi è l'aggiunta dello stesso comportamento usando una costante:

#!/usr/bin/perl

use strict;
use warnings;

use constant false => 0;
use constant true  => 1;

my $val1 = true;
my $val2 = false;

print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

Le righe contrassegnate in "usa costante" definiscono una costante denominata true che restituisce sempre 1 e una costante denominata false che valuta sempre per 0. A causa del modo in cui le costanti sono definite in Perl, anche le seguenti righe di codice falliscono:

true = 0;
true = false;

Il messaggio di errore dovrebbe dire qualcosa come "Impossibile modificare la costante nell'assegnazione scalare".

Ho visto che in uno dei commenti hai chiesto di confrontare le stringhe. Dovresti sapere che, poiché Perl combina stringhe e tipi numerici in variabili scalari, hai una sintassi diversa per confrontare stringhe e numeri:

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";
}

La differenza tra questi operatori è una fonte di confusione molto comune in Perl.


5
use warnings;anziché#! perl -w
Brad Gilbert il

11
L'uso delle costanti come macro per i poveri è pericoloso. Questi esempi di codice non sono equivalenti: if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }, che potrebbe non essere ovvio per un osservatore casuale. (E sì, l'ultimo esempio è uno stile di programmazione scadente, ma non è questo il punto).
Zano,

16

Mi raccomando use boolean;. Tuttavia, devi installare il modulo booleano da cpan.


7
In Perl, come nella vita, ci sono molte verità. Gli inesperti amano scrivere cose stupide come if ($my_true_value == true). Far finta che esista un'unica vera verità è, nella mia esperienza, un percorso verso il dolore e un codice inefficiente.
giovedì

2
Perl è filosofico per natura
ILMostro_7

13

I miei preferiti sono sempre stati

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

che è completamente indipendente dalla rappresentazione interna.


5
Brillante. Hai risolto da solo il linguaggio di programmazione Perl!
Nostalg.io,

8

Mi sono imbattuto in un tutorial che spiega bene quali valori sono veri e falsi in Perl . Si afferma che:

I seguenti valori scalari sono considerati falsi:

  • undef - il valore indefinito
  • 0 il numero 0, anche se lo scrivi come 000 o 0,0
  • '' la stringa vuota.
  • '0' la stringa che contiene una singola cifra 0.

Tutti gli altri valori scalari, inclusi i seguenti, sono veri:

  • 1 qualsiasi numero diverso da 0
  • ' ' la stringa con uno spazio al suo interno
  • '00' due o più 0 caratteri in una stringa
  • "0\n" uno 0 seguito da una nuova riga
  • 'true'
  • 'false' sì, anche la stringa 'false' viene valutata vera.

C'è un altro buon tutorial che spiega su Perl vero e falso .


6

Bella spiegazione data da bobf per i valori booleani: vero o falso? Una guida di riferimento rapido

Test di verità per valori diversi

                       Result of the expression when $var is:

Expression          | 1      | '0.0'  | a string | 0     | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var )          | true   | true   | true     | false | false     | false
if( defined $var )  | true   | true   | true     | true  | true      | false
if( $var eq '' )    | false  | false  | false    | false | true      | true
if( $var == 0 )     | false  | true   | true     | true  | true      | true

Risposta scadente, ma una fonte forte e rispettabile in perlmonks.org. Sarebbe bello avere dei contenuti reali invece di un commento e un link. : - /
ILMostro_7

0

usa il seguente prefisso di file, questo aggiungerà al tuo script perl eTRUE ed eFALSE, sarà in realtà REAL (!) vero e falso (proprio come Java)

#!/usr/bin/perl
use 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' )
             };

In realtà, ci sono alcuni motivi per cui dovresti usarlo.

La mia ragione è che lavorando con JSON, ho 0 e 1 come valori per le chiavi, ma questo hack assicurerà che i valori corretti vengano mantenuti lungo il tuo script.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.