Αλήθεια τιμών#

Πριν από τη λογική, οι τιμές πάνω στις οποίες ενεργεί η λογική. Η Perl δεν έχει αποκλειστικό λογικό τύπο. Κάθε βαθμωτό είναι είτε αληθές είτε ψευδές όταν χρησιμοποιείται σε λογικό περιβάλλον, και ο κανόνας είναι σύντομος:

Ένα βαθμωτό είναι ψευδές αν είναι μία από τις τέσσερις τιμές undef, ο ακέραιος 0, η συμβολοσειρά "", ή η συμβολοσειρά "0". Οτιδήποτε άλλο είναι αληθές.

Τέσσερις ψευδείς τιμές, κάθε άλλο βαθμωτό — συμπεριλαμβανομένων των συμβολοσειρών "00", "0.0", "0E0", και "false" — είναι αληθές.

if (0)        { ... }   # false  -- the integer zero
if (0.0)      { ... }   # false  -- numerically zero
if ("")       { ... }   # false  -- empty string
if ("0")      { ... }   # false  -- the string "0"
if (undef)    { ... }   # false  -- undefined value

if ("00")     { ... }   # TRUE   -- non-empty, not the string "0"
if ("0.0")    { ... }   # TRUE   -- non-empty, not the string "0"
if ("0 but true") { ... } # TRUE -- non-empty, not the string "0"
if (" ")      { ... }   # TRUE   -- single space is non-empty
if ("false")  { ... }   # TRUE   -- it's just a 5-character string

Το ιδίωμα "0 but true" δεν είναι αστείο. Ορισμένα API της Perl επιστρέφουν μια τιμή που πρέπει να συγκρίνεται ίση με μηδέν αριθμητικά (ώστε ένας αριθμητικός έλεγχος να κάνει το σωστό) αλλά να είναι αληθής σε λογικό περιβάλλον. Η κλασική περίπτωση είναι το ioctl() — η επιτυχία που θα επέστρεφε κυριολεκτικά μηδέν θα ελεγχόταν ως ψευδής. Η συμβολοσειρά "0 but true" είναι αριθμητικά μηδέν (με μια προειδοποίηση που καταστέλλεται κατόπιν ιστορικής συμφωνίας) και λογικά αληθής επειδή δεν ανήκει στο τετραστοιχειακό σύνολο των ψευδών.

my $rc = ioctl($fh, $cmd, $buf);
$rc == 0       and warn "numeric zero";   # would fire on success
$rc            or  warn "boolean false";  # FIRES if API returned 0
                                          # but NOT if "0 but true"

Δύο γεύσεις σύγκρισης#

Η Perl διαθέτει παράλληλες οικογένειες τελεστών σύγκρισης επειδή έχει παράλληλες έννοιες ισότητας. Οι αριθμοί συγκρίνονται αριθμητικά· οι συμβολοσειρές συγκρίνονται λεξικογραφικά. Η λανθασμένη οικογένεια στον λανθασμένο τύπο είναι ένα από τα πιο κοινά σφάλματα στην αρχάρια Perl.

Έλεγχος

Αριθμητικός

Συμβολοσειρά

ίσο

==

eq

άνισο

!=

ne

μικρότερο από

<

lt

μεγαλύτερο από

>

gt

μικρότερο ή ίσο

<=

le

μεγαλύτερο ή ίσο

>=

ge

τριμερής (sort)

<=>

cmp

Το == σε συμβολοσειρές πάντα πετυχαίνει για οποιεσδήποτε δύο μη αριθμητικές συμβολοσειρές — και οι δύο μετατρέπονται σε 0, και το 0 == 0 είναι αληθές:

"foo" == "bar";    # TRUE  -- both stringify to numeric 0
"foo" eq "bar";    # FALSE -- the actual question

"10" eq 10;        # TRUE  -- string "10" equals numeric 10 stringified
"10" == 10;        # TRUE  -- 10 == 10 numerically
"10" lt "9";       # TRUE  -- lexical: "1" < "9"
"10" <  "9";       # FALSE -- numeric: 10 > 9

Τα <=> και cmp επιστρέφουν -1, 0, ή +1 — η τυπική μορφή συγκριτή ταξινόμησης. Δεν είναι λογικοί τελεστές με τη στενή έννοια, αλλά εμφανίζονται μέσα σε λογικά περιβάλλοντα αρκετά συχνά ώστε να αξίζει να τους γνωρίζετε.

Γιατί αυτό έχει σημασία για τη λογική#

Κάθε λογικός τελεστής στην Perl — &&, ||, //, !, xor, and, or, not — χρησιμοποιεί το παραπάνω τετραστοιχειακό σύνολο των ψευδών ως κανόνα εισόδου του. Όποτε ένα παρακάτω κεφάλαιο λέει «αν το $x είναι ψευδές», αυτό ακριβώς εννοεί: το $x είναι undef, 0, "", ή "0". Όποτε λέει «αν το $x είναι αληθές», το $x είναι οτιδήποτε άλλο.

Δύο συνέπειες που αξίζει να έχετε υπόψη:

  1. Ένα βαθμωτό μπορεί να είναι αληθές χωρίς να είναι λογικά αληθής τιμή. Συμβολοσειρές, αναφορές, blessed αντικείμενα, μεγάλοι αριθμοί — όλα αληθή. Όταν ρωτάτε «είναι αυτό αληθές;» δεν ρωτάτε «είναι αυτό ίσο με 1;» — ρωτάτε «δεν ανήκει αυτό στο σύνολο των ψευδών;».

  2. Το αποτέλεσμα ενός λογικού τελεστή δεν είναι πάντα 1 ή 0. Το επόμενο κεφάλαιο καλύπτει αυτό λεπτομερώς. Συνοπτικά: τα && και || επιστρέφουν έναν από τους τελεστέους τους, όχι μια κανονικοποιημένη λογική τιμή. Αυτό είναι χαρακτηριστικό, όχι ιδιοτροπία, και πολλά ιδιώματα της Perl εξαρτώνται από αυτό.

Δείτε επίσης#