Λίστες

all#

Ελέγχει αν το BLOCK επιστρέφει αληθές για κάθε στοιχείο της LIST.

Η all διατρέχει τη LIST από αριστερά προς τα δεξιά, ψευδωνυμώντας το $_ σε κάθε στοιχείο διαδοχικά και αξιολογώντας το BLOCK με εκείνο το στοιχείο. Επιστρέφει αληθή τιμή αν κάθε αξιολόγηση δίνει αλήθεια, και ψευδή τιμή μόλις κάποια αξιολόγηση δώσει ψεύδος. Μόλις ένα στοιχείο κάνει το μπλοκ ψευδές, η all σταματά και επιστρέφει — δεν αξιολογεί το μπλοκ για τα υπόλοιπα στοιχεία.

Αυτή είναι η all σε επίπεδο γλώσσας ως δεσμευμένη λέξη, ενεργοποιούμενη από το χαρακτηριστικό keyword_all. Είναι διακριτή από την List::Util::all — δείτε Οριακές περιπτώσεις παρακάτω.

Σύνοψη#

use feature 'keyword_all';
no warnings 'experimental::keyword_all';

all { /\w+/ } @words;
all { defined $_ } @list;        # canonical "all defined" check
all { $_ > 0 } @numbers;

Τι επιστρέφεται#

Μια λογική τιμή. Αληθής αν κάθε στοιχείο περάσει, ψευδής διαφορετικά. Οι ακριβείς τιμές αληθές/ψευδές είναι απροσδιόριστες — αντιμετωπίστε το αποτέλεσμα ως συνθήκη, όχι ως δεδομένο προς διάδοση.

Η κενή λίστα επιστρέφει αληθές. Αυτή είναι η κενή αλήθεια: η δήλωση «κάθε στοιχείο ικανοποιεί το BLOCK» είναι τετριμμένα αληθής όταν δεν υπάρχουν στοιχεία προς έλεγχο. Είναι η πλέον συνηθισμένη πηγή έκπληξης με την all:

all { $_ > 0 } ();               # TRUE — no elements, nothing to fail

Προστατευτείτε με ρητό έλεγχο μεγέθους όταν μια κενή λίστα πρέπει να αντιμετωπίζεται ως αποτυχία:

if (@numbers && all { $_ > 0 } @numbers) { ... }

Καθολική κατάσταση που επηρεάζει#

  • $_ — ψευδωνυμίζεται σε κάθε στοιχείο της LIST διαδοχικά για τη διάρκεια του μπλοκ. Επειδή πρόκειται για ψευδώνυμο και όχι αντίγραφο, η εκχώρηση στο $_ μέσα στο μπλοκ μεταβάλλει το υποκείμενο στοιχείο της λίστας. Η προηγούμενη τιμή του $_ επαναφέρεται όταν επιστρέφει η all.

Παραδείγματα#

Έλεγχος ότι κάθε τιμή σε μια λίστα είναι ορισμένη — η κανονική χρήση:

my @row = get_record();
die "missing field" unless all { defined $_ } @row;

Έλεγχος ότι κάθε αριθμός είναι θετικός:

my @prices = (1.99, 4.50, 0.99);
say "ok" if all { $_ > 0 } @prices;         # ok

Επικύρωση εγγραφής όπου κάθε πεδίο πρέπει να ταιριάζει στο δικό του κατηγόρημα. Συνδυάστε πολλαπλούς ελέγχους μέσα στο μπλοκ αντί να αλυσιδώνετε κλήσεις της all:

my @fields = ($name, $age, $email);
my $ok = all {
    defined $_ && length $_ > 0
} @fields;

Συνδυάστε την all με την any για έναν αποκλειστικό έλεγχο — τουλάχιστον μία αντιστοιχία, αλλά όχι κάθε στοιχείο ίδιο:

if (any { $_ eq 'admin' } @roles
    && !all { $_ eq 'admin' } @roles) {
    say "mixed roles, including admin";
}

Συμπεριφορά βραχυκυκλώματος: το μπλοκ τρέχει μόνο μέχρι την πρώτη αποτυχία. Χρήσιμο για κατηγορήματα με παρενέργειες ή κόστος:

all { expensive_check($_) } @candidates;    # stops at first failure

Οριακές περιπτώσεις#

  • Η κενή λίστα επιστρέφει αληθές. Κενή αλήθεια. Προστατευτείτε με @list && all { ... } @list όταν το άδειασμα πρέπει να αποτυγχάνει.

  • Βραχυκυκλώνει στο πρώτο ψευδές. Το μπλοκ δεν καλείται για κανένα στοιχείο μετά την πρώτη αποτυχία. Μη βασίζεστε σε παρενέργειες του μπλοκ που να εκτελούνται για κάθε στοιχείο — χρησιμοποιήστε βρόχο for αν τις χρειάζεστε.

  • Το $_ είναι ψευδώνυμο, όχι αντίγραφο. Η τροποποίηση του $_ μέσα στο μπλοκ τροποποιεί το στοιχείο της λίστας:

    my @xs = (1, 2, 3);
    all { $_++; $_ > 0 } @xs;
    # @xs is now (2, 3, 4)
    
  • Πειραματικό υπό 5.42. Το χαρακτηριστικό εκπέμπει προειδοποίηση κατά τη μεταγλώττιση στην κατηγορία experimental::keyword_all εκτός αν εκείνη η κατηγορία αποσιωπηθεί:

    no warnings 'experimental::keyword_all';
    
  • Δεν είναι το ίδιο με την List::Util::all. Η ενσωματωμένη είναι δεσμευμένη λέξη της γλώσσας ενεργοποιούμενη από το χαρακτηριστικό keyword_all και αναλύει το BLOCK ως πραγματικό μπλοκ (χωρίς αρχική sub, χωρίς τελευταίο κόμμα). Η List::Util::all είναι κανονική υπορουτίνα εισαγμένη από άρθρωμα και δέχεται όρισμα αναφοράς κώδικα / πρωτοτύπου μπλοκ. Για τους περισσότερους πρακτικούς σκοπούς συμπεριφέρονται το ίδιο σε μη κενές λίστες, αλλά:

    • Η μορφή ως δεσμευμένη λέξη είναι κατασκευή σε επίπεδο συντακτικού αναλυτή και μπορεί να βελτιστοποιηθεί πιο επιθετικά.

    • Οι δύο δεν μοιράζονται ούτε υλοποίηση ούτε κατηγορία προειδοποίησης.

    • Κώδικας που πρέπει να τρέχει σε perls προγενέστερες της 5.42 θα πρέπει να χρησιμοποιεί την List::Util::all.

  • Ισοδύναμη μορφή με grep. Το all { COND } @xs είναι σημασιολογικά ισοδύναμο με @xs == grep { COND } @xs — αλλά η grep αξιολογεί πάντα το μπλοκ για κάθε στοιχείο, οπότε στερείται τη συμπεριφορά βραχυκυκλώματος της all.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

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

  • any — αληθές αν το μπλοκ επιστρέφει αληθές για τουλάχιστον ένα στοιχείο· ο κατοπτρικός τελεστής της all

  • grep — αξιολογεί το μπλοκ για κάθε στοιχείο και επιστρέφει τις αντιστοιχίες· το scalar @list == grep { } @list είναι η all χωρίς το βραχυκύκλωμα

  • defined — το κατηγόρημα μέσα στον κανονικό έλεγχο all { defined $_ } @list

  • List::Util::all — ισοδύναμο σε επίπεδο αρθρώματος διαθέσιμο σε perls παλαιότερες της 5.42· παρέχει επίσης τις none και notall που δεν έχουν αντίστοιχο σε επίπεδο γλώσσας

  • List::Util::any — αντίστοιχο σε επίπεδο αρθρώματος της δεσμευμένης λέξης any, μαζί με τις none και notall για τις αντίθετες πολικότητες