Τελεστές#
Η Perl γράφει τους λογικούς τελεστές δύο φορές, σε δύο διαφορετικές κλάσεις προτεραιότητας. Οι συμβολικές μορφές σε στιλ C (&&, ||, !) δένουν σφιχτά· οι λεκτικές μορφές (and, or, not) δένουν πολύ χαλαρά. Υπάρχει επίσης το // για το ιδίωμα defined-or, το xor για το αποκλειστικό «ή», και ο τριαδικός ?: που είναι λογική επιλογή σε μεταμφίεση.
Ο πλήρης κατάλογος#
Τελεστής | Διαβάζεται ως | Επιστρέφει | Προτεραιότητα |
|---|---|---|---|
| όχι | κανονικοποιημένο | υψηλή |
| και | αριστερό αν ψευδές, αλλιώς δεξί (ο τελεστέος) | υψηλή |
| ή | αριστερό αν αληθές, αλλιώς δεξί (ο τελεστέος) | υψηλή |
| defined-or | αριστερό αν ορισμένο, αλλιώς δεξί (ο τελεστέος) | υψηλή |
| αποκλειστικό ή | κανονικοποιημένο | πολύ χαμηλή |
| όχι | κανονικοποιημένο | πολύ χαμηλή |
| και | αριστερό αν ψευδές, αλλιώς δεξί (ο τελεστέος) | πολύ χαμηλή |
| ή | αριστερό αν αληθές, αλλιώς δεξί (ο τελεστέος) | πολύ χαμηλή |
| τριαδικός | μεσαίο αν η συνθήκη αληθής, αλλιώς δεξί (τελεστέος) | χαμηλή |
Δύο πράγματα σε αυτόν τον πίνακα κάνουν το μεγαλύτερο μέρος της δουλειάς:
Τα
&&και||επιστρέφουν τελεστέο, όχι λογική τιμή. Αυτή είναι η ιδιότητα που κάνει τα ιδιώματα της Perl να λειτουργούν όπως λειτουργούν. Δείτε παρακάτω.Οι συμβολικές και λεκτικές μορφές διαφέρουν στην προτεραιότητα, όχι στο νόημα. Τα
&&καιandυπολογίζουν την ίδια λογική συνάρτηση. Διαφέρουν στο πόσο σφιχτά δένουν με τους άλλους τελεστές γύρω τους. Γι” αυτό βλέπετεor dieμετά από κλήσεις συναρτήσεων αλλά||μέσα σε εκφράσεις — το κεφάλαιο για το ιδίωμαor dieεξηγεί.
Βραχυκύκλωμα και ο κανόνας επιστροφής τελεστέου#
Τα && και || αποτιμώνται από αριστερά προς τα δεξιά και σταματούν μόλις προσδιοριστεί το αποτέλεσμα.
A && B— αν τοAείναι ψευδές, επιστρέφει τοAχωρίς να αποτιμήσει τοB. Αλλιώς επιστρέφει τοB.A || B— αν τοAείναι αληθές, επιστρέφει τοAχωρίς να αποτιμήσει τοB. Αλλιώς επιστρέφει τοB.
Καθοριστικά, η τιμή επιστροφής είναι ο ίδιος ο τελεστέος, όχι ένα κανονικοποιημένο αληθές/ψευδές. Αυτό κάνει μοτίβα όπως $config{port} || 8080 να λειτουργούν: αν το $config{port} έχει οριστεί (αληθές), η έκφραση είναι η τιμή του $config{port}· αν όχι, είναι το 8080.
my $port = $config{port} || 8080;
my $name = $user_input || "anonymous";
my $list = shift || [];
Η ίδια ιδιότητα τροφοδοτεί το or die:
open my $fh, '<', $path or die "open $path: $!";
# ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
# if open returns true, the right-hand operand
# the whole expression is never evaluated
# is true and we move on
Το open επιστρέφει αληθές στην επιτυχία, undef στην αποτυχία. Στην επιτυχία το βραχυκύκλωμα σταματά στα αριστερά και το die ποτέ δεν εκτελείται. Στην αποτυχία αποτιμάται ο δεξής τελεστέος, που είναι η κλήση die.
// — defined-or#
Το || χειρίζεται τα 0, "", και "0" το ίδιο με το undef. Μερικές φορές αυτό είναι λάθος: ένα ρυθμισμένο 0 είναι πραγματική τιμή, όχι ελλείπουσα. Το // βραχυκυκλώνει με βάση τον ορισμό αντί της αλήθειας:
A // B— αν τοAείναι ορισμένο, επιστρέφει τοA. Αλλιώς επιστρέφει τοB.
my $port = $config{port} || 8080; # 0 means "use default" — wrong
my $port = $config{port} // 8080; # 0 means "0", undef means "use default"
my $verbose = $opt{verbose} // 0; # 0 is a real choice
Οι σύνθετες μορφές ανάθεσης ||= και //= σας απαλλάσσουν από την επανάληψη της μεταβλητής στα αριστερά:
$config{port} //= 8080; # set only if currently undef
$cache{$key} ||= compute($key); # set if currently false
Το xor και η απουσία μορφής υψηλής προτεραιότητας#
Δεν υπάρχει ^^ στην Perl. Το xor υπάρχει μόνο ως λεκτική μορφή πολύ χαμηλής προτεραιότητας, και σε αντίθεση με τα and/or δεν βραχυκυκλώνει (δεν μπορεί — και οι δύο πλευρές πρέπει να αποτιμηθούν για να προσδιοριστεί το αποτέλεσμα). Επιστρέφει κανονικοποιημένο 1 ή "", όχι τελεστέο.
if ($admin xor $guest) { ... } # exactly one of the two
Για xor πάνω σε τιμές αντί για αλήθεια, το κατά bit ^ εφαρμόζεται σε ακεραίους — καλύπτεται στο κεφάλαιο εφαρμογών.
! και not#
Και τα δύο αρνούνται. Το ! είναι η συμβολική μορφή υψηλής προτεραιότητας· το not είναι η λεκτική μορφή χαμηλής προτεραιότητας. Και τα δύο επιστρέφουν κανονικοποιημένη τιμή: 1 για «ο τελεστέος ήταν ψευδής», κενή συμβολοσειρά "" για «ο τελεστέος ήταν αληθής».
my $missing = ! $config{port}; # 1 if port is unset/0/""/"0"
return if not @items; # cleaner reading than `if !@items`
Ο τριαδικός ?:#
COND ? X : Y είναι λογική επιλογή: αν το COND είναι αληθές η τιμή είναι X, αλλιώς Y. Δεν είναι απλώς συντακτική ζάχαρη για if/else επειδή είναι έκφραση — έχει τιμή, μπορεί να ανατεθεί, να επιστραφεί, να περάσει ως όρισμα.
my $label = $count == 1 ? "1 item" : "$count items";
return $ok ? \%result : undef;
Προσοχή στην εμφώλευση: το $a ? $b : $c ? $d : $e αναλύεται ως $a ? $b : ($c ? $d : $e) — το αλυσιδωτό ?: είναι δεξιά προσεταιριστικό, που συνήθως είναι αυτό που θέλετε για μια κλιμάκωση if/elsif/else αλλά αξίζει να το γνωρίζετε αντί να μαντεύετε.
Γιατί υπάρχουν οι λεκτικές μορφές: προτεραιότητα, όχι στιλ#
Το || δένει σφιχτότερα από το =. Το or δένει χαλαρότερα από το = (ή το ,, ή οτιδήποτε άλλο συμβατικού βάρους). Αυτός είναι ο μοναδικός λόγος που υπάρχουν οι λεκτικές μορφές.
my $fh = open $h, '<', $path || die "no $path: $!";
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^
# parses as: open $h, '<', ($path || die "no $path: $!")
# which is: open the file named "either $path or the die-message"
# which is: catastrophe.
my $fh = open $h, '<', $path or die "no $path: $!";
# parses as: ($fh = open $h, '<', $path) or die "no $path: $!"
# which does what you meant.
Εμπειρικός κανόνας:
Μέσα σε μια έκφραση, όπου θέλετε η τιμή να ρέει σε μια μεταβλητή ή σε άλλον τελεστή: χρησιμοποιήστε
&&,||,!,//.Μετά από μια πρόταση, όπου θέλετε μια παρενέργεια (
die,warn,return) να ενεργοποιηθεί υπό συνθήκη: χρησιμοποιήστεor,and,not.
Τι πρέπει να θυμάστε από αυτό το κεφάλαιο#
Τα
&&και||δεν είναι κατηγορήματα που επιστρέφουν 1 ή 0 — επιστρέφουν έναν από τους τελεστέους τους. Αυτό είναι το θεμέλιο των||,||=,or die, και των περισσότερων σύντομων ιδιωμάτων προεπιλογής.Το
//είναι το||για ορισμό, όχι αλήθεια. Χρησιμοποιήστε το όταν το0είναι έγκυρη τιμή.Οι λεκτικές μορφές υπάρχουν για να δένουν πιο χαλαρά από την ανάθεση, όχι για στιλ.
Το
xorυπάρχει, δεν έχει συμβολική μορφή, δεν βραχυκυκλώνει.
Δείτε επίσης#
perlop — Λογικοί — ο σύντροφος αναφοράς, με το πλαίσιο των γραμμών προτεραιότητας και τις σημειώσεις ειδικά για το PetaPerl.
perlop — Προτεραιότητα — ο πλήρης πίνακας· οι γραμμές 5, 15, 16, 22, 23, 24 είναι οι τελεστές αυτής της σελίδας.
perlop — Τριαδικός —
?:ως λογική επιλογή.