evalbytes#
Μεταγλωττίζει και εκτελεί μια συμβολοσειρά πηγαίου κώδικα Perl, αναγκάζοντας την πηγή να ερμηνευτεί ως bytes αντί ως χαρακτήρες.
Η evalbytes είναι το byte-προσανατολισμένο δίδυμο της string eval. Δέχεται μια EXPR (ή την $_ όταν η EXPR παραλείπεται), αντιμετωπίζει τη συμβολοσειρά ως ωμή ροή bytes και την αναλύει ως πηγαίο κώδικα Perl. Η ανάλυση είναι μονωμένη από την pragma use utf8 του καλούντος: όποιους κανόνες κωδικοποίησης δηλώνει η ίδια η συμβολοσειρά, αυτοί υπερισχύουν. Χρησιμοποιήστε την όταν ο κώδικας που πρόκειται να μεταγλωττίσετε διαβάστηκε από δίσκο, από το δίκτυο ή από κάποιο βήμα build και χρειάζεστε ο αναλυτής να δει ακριβώς τα bytes που του δώσατε.
Σύνοψη#
evalbytes EXPR
evalbytes
CORE::evalbytes EXPR # when the feature is not enabled
Τι επιστρέφεται#
Σε βαθμωτό περιβάλλον, η τιμή της τελευταίας έκφρασης που αποτιμήθηκε· σε περιβάλλον λίστας, μια λίστα. Σε σφάλμα μεταγλώττισης ή χρόνου εκτέλεσης, undef (ή κενή λίστα) και η $@ τίθεται στο μήνυμα σφάλματος· η $@ είναι η κενή συμβολοσειρά σε επιτυχία. Η μορφή επιστροφής ταιριάζει ακριβώς με την string eval - η μόνη διαφορά είναι ο τρόπος αποκωδικοποίησης του ίδιου του κειμένου της πηγής.
my $result = evalbytes $source;
die $@ if $@;
Πώς διαφέρει από την string eval#
Δύο συγκεκριμένες συμπεριφορές διακρίνουν την evalbytes από την eval EXPR:
Η πηγή αναλύεται ως bytes. Κάθε οκτάδα στη συμβολοσειρά είναι ξεχωριστός χαρακτήρας εισόδου για τον λεκτικό αναλυτή, ανεξάρτητα από το αν η συμβολοσειρά είναι εσωτερικά σημειωμένη ως
utf8. Μια ακολουθία UTF-8 πολλαπλών bytes στην πηγή εμφανίζεται στον αναλυτή ως τα επιμέρους bytes, όχι ως το αποκωδικοποιημένο σημείο κώδικα.Σημεία κώδικα πάνω από το 255 είναι σκληρό σφάλμα. Αν η συμβολοσειρά περιέχει οποιονδήποτε χαρακτήρα του οποίου ο τακτικός αριθμός υπερβαίνει το
0xFF, δεν μπορεί να είναι ροή bytes και η μεταγλώττιση αποτυγχάνει μεWide character in evalαποθηκευμένο στην$@. Υποβαθμίστε πρώτα με τηνutf8::encodeαν η πηγή κρατά αυτή τη στιγμή αποκωδικοποιημένο κείμενο.
Οι use utf8 και no utf8 μέσα στον υπό αξιολόγηση κώδικα έχουν τη συνηθισμένη τους επίδραση: η pragma ενεργοποιείται μόλις την φτάσει ο αναλυτής και επηρεάζει το υπόλοιπο εκείνης της μεταγλώττισης. Είναι το εξωτερικό πλαίσιο της πηγής που είναι καθηλωμένο στα bytes, όχι αυτό που δηλώνει η ίδια η πηγή.
Ενεργοποίηση του ονόματος χωρίς CORE::#
Η evalbytes είναι feature-gated. Για να την καλέσετε ως bareword:
use feature 'evalbytes';
Μια δήλωση use v5.16 (ή υψηλότερη) ενεργοποιεί αυτόματα το χαρακτηριστικό evalbytes, μαζί με το υπόλοιπο bundle χαρακτηριστικών :5.16. Χωρίς κάποιο από τα δύο, το μη πλήρως κατονομασμένο όνομα δεν αναγνωρίζεται και πρέπει να γράψετε ρητά CORE::evalbytes - χρήσιμο μέσα σε παραγόμενο κώδικα ή σε μονόγραμμα που δεν φέρουν δήλωση έκδοσης.
use v5.16;
my $n = evalbytes '1 + 2'; # 3
# no feature, no version bundle:
my $n = CORE::evalbytes '1 + 2'; # 3
Καθολική κατάσταση που επηρεάζει#
$@- καθαρίζεται πριν τη μεταγλώττιση, κατόπιν τίθεται στο μήνυμα σφάλματος σε αποτυχία ή στην κενή συμβολοσειρά σε επιτυχία. Ίδιο συμβόλαιο με τηνeval.$_- διαβάζεται ως το κείμενο πηγής όταν ηEXPRπαραλείπεται.
Source filters ενεργοποιημένα μέσα στον υπό αξιολόγηση κώδικα εφαρμόζονται στον ίδιο τον κώδικα, ακριβώς όπως θα έκαναν μέσα σε μια string eval. Το filter βλέπει τα ίδια bytes που βλέπει ο αναλυτής.
Παραδείγματα#
Αποτίμηση μιας κυριολεκτικής συμβολοσειράς bytes - καμία έκπληξη, καμία επιλογή κωδικοποίησης:
use feature 'evalbytes';
my $n = evalbytes 'my $x = 40; $x + 2'; # 42
Αποτίμηση πηγής που διαβάστηκε από αρχείο που είναι γνωστό ότι είναι κωδικοποιημένο σε UTF-8 αλλά για το οποίο η δηλωμένη pragma μέσα στην πηγή είναι αυτό που πρέπει να διέπει την ανάλυση:
use feature 'evalbytes';
open my $fh, '<:raw', 'script.pl' or die $!;
my $src = do { local $/; <$fh> };
my @values = evalbytes $src;
die "compile failed: $@" if $@;
Η ανάγνωση με :raw διατηρεί τη $src ως συμβολοσειρά bytes. Η evalbytes τότε τροφοδοτεί αυτά τα bytes στον αναλυτή αυτούσια· μια γραμμή use utf8; στην κορυφή του σεναρίου θα κάνει τη δική της δουλειά μόλις τη φτάσει ο αναλυτής.
Συγκρίνετε με τη string eval όταν ο καλών έχει use utf8:
use utf8;
use feature 'evalbytes';
my $src = "length('caf\xc3\xa9')"; # bytes for 'café' in UTF-8
print eval $src; # 3 (characters: c, a, f, é)
print "\n";
print evalbytes $src; # 5 (bytes: c, a, f, 0xC3, 0xA9)
print "\n";
Υπό use utf8 το ίδιο το κυριολεκτικό "length('caf\xc3\xa9')" του καλούντος είναι συμβολοσειρά χαρακτήρων για την eval, οπότε η length μέσα στον υπό αξιολόγηση κώδικα βλέπει έναν χαρακτήρα é. Η evalbytes αναγκάζει την ίδια πηγή να αναλυθεί ως η ακολουθία bytes c a f 0xC3 0xA9, οπότε η length αναφέρει το πλήθος bytes.
Πιάσιμο ενός wide-character σφάλματος:
use feature 'evalbytes';
my $src = "print \x{2603}"; # contains U+2603 SNOWMAN
evalbytes $src;
warn "rejected: $@" if $@; # "Wide character in eval ..."
Παράλειψη της EXPR - η πηγή προέρχεται από την $_:
use feature 'evalbytes';
for ('1+1', '2*3', '10-7') {
my $r = evalbytes;
print "$_ = $r\n";
}
Οριακές περιπτώσεις#
Wide character στην πηγή: οποιοδήποτε σημείο κώδικα πάνω από το
0xFFματαιώνει τη μεταγλώττιση και αφήνειWide character in evalστην$@. Τρέξτεutf8::encodeστην πηγή (ή διαβάστε το αρχείο με:raw) πριν την κλήση.Η
use utf8είναι τοπική στον υπό αξιολόγηση κώδικα. Επηρεάζει κυριολεκτικά συμβολοσειρών και αναγνωριστικά μέσα στο αποτιμώμενο κείμενο μόλις ο αναλυτής φτάσει στη γραμμή της pragma. Δεν αλλάζει τον τρόπο που ηevalbytesπλαισιώνει την εξωτερική πηγή - εκείνο το πλαίσιο είναι πάντα «bytes».Το χαρακτηριστικό δεν είναι ενεργοποιημένο: χωρίς
use feature 'evalbytes'και χωρίς bundleuse v5.16+, το bareword δεν αναγνωρίζεται. ΓράψτεCORE::evalbytesγια να παρακάμψετε την πύλη χαρακτηριστικού.evalbytesχωρίς όρισμα και με$_undef: μεταγλωττίζει κενή συμβολοσειρά, πράγμα που πετυχαίνει και επιστρέφειundefσε βαθμωτό περιβάλλον, την κενή λίστα σε περιβάλλον λίστας, με την$@κενή.Τα source filters μέσα στον υπό αξιολόγηση κώδικα βλέπουν τη ροή bytes. Ένα filter που περιμένει αποκωδικοποιημένους χαρακτήρες θα δυσλειτουργήσει· γράψτε filters για την
evalbytesσε όρους bytes.Λεξιλογικά και κατάσταση πακέτου: ίδιοι κανόνες με τη string
eval. Ο υπό αξιολόγηση κώδικας μοιράζεται το τρέχον πακέτο του καλούντος και βλέπει τα εντός εμβέλειας λεξιλογικά του καλούντος· οι δικές του μεταβλητέςmyεξαφανίζονται όταν ολοκληρωθεί η eval.dieμέσα σεevalbytes: πιάνεται με τον ίδιο τρόπο όπως για τηνeval. Η εκτοξευμένη τιμή προσγειώνεται στην$@· η εκτέλεση συνεχίζεται μετά την κλήσηevalbytes.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
eval- το αντίστοιχο σε character-mode· αναλύει τηνEXPRσύμφωνα με το Unicode πλαίσιο του καλούντος, οπότε ηuse utf8στον καλούντα αλλάζει τον τρόπο ερμηνείας της πηγήςdie- εκτοξεύει εξαίρεση μέσα από υπό αξιολόγηση κώδικα· θέτει την$@όπως κάθε άλλο σφάλμα χρόνου εκτέλεσηςdo- μεταγλωττίζει και εκτελεί ένα αρχείο· παίρνει την πηγή του από τον δίσκο αντί από συμβολοσειρά και δεν επηρεάζεται από τοutf8πλαίσιο του καλούντοςrequire- φορτώνει και μεταγλωττίζει ένα αρχείο μία φορά· το πρότυπο εργαλείο όταν η πηγή βρίσκεται στον δίσκο και πρέπει να εκτελεστεί μόνο κατά την πρώτη αναφοράutf8- η pragma που ελέγχει τη σημασιολογία χαρακτήρων έναντι bytes στα κυριολεκτικά συμβολοσειρών· ηevalbytesυπάρχει ακριβώς για να καθηλώσει το εξωτερικό πλαίσιο στα bytes ανεξάρτητα από αυτή την pragma$@- η θέση σφάλματος που συμπληρώνεται σε αποτυχία τηςevalbytes, καθαρίζεται σε επιτυχία