Διαχείριση locale#

Ένα locale είναι το σύνολο των πολιτισμικών συμβάσεων που ακολουθεί ένα πρόγραμμα όταν ταξινομεί κείμενο, αλλάζει πεζά/κεφαλαία, μορφοποιεί αριθμούς και νομισματικά ποσά, ονομάζει τις ημέρες της εβδομάδας ή γράφει ένα μήνυμα σφάλματος. Ο ίδιος πίνακας λέξεων ταξινομείται με έναν τρόπο υπό ένα σουηδικό locale και με άλλον υπό ένα γερμανικό· ο αριθμός δωδεκάμισι εκτυπώνεται ως 12.5 σε μία χώρα και ως 12,5 σε μια άλλη. Η διαχείριση locale είναι ο τρόπος με τον οποίο η Perl επιτρέπει σε ένα μόνο πρόγραμμα να προσαρμόζεται σε αυτές τις συμβάσεις κατά τον χρόνο εκτέλεσης, αντί να ενσωματώνει σταθερά τους κανόνες μιας χώρας.

Εξ ορισμού η PetaPerl αγνοεί εντελώς το locale: κάθε ενσωματωμένη συνάρτηση συμπεριφέρεται με τον ίδιο τρόπο ανεξάρτητα από το περιβάλλον του χρήστη, χρησιμοποιώντας τις συμβάσεις C/POSIX (συνταξιοθεσία ASCII, . ως υποδιαστολή, αγγλικά ονόματα μηνών). Ενεργοποιείτε την επίγνωση locale, μία λεξιλογική εμβέλεια τη φορά, με την pragma use locale. Αυτή η σελίδα καλύπτει τι ενεργοποιεί αυτή η pragma, ποιες λειτουργίες επηρεάζει, πώς να ορίσετε και να επιθεωρήσετε το ενεργό locale, και πού αλληλεπιδρούν το locale και το Unicode.

Τι είναι ένα locale#

Η βιβλιοθήκη C του συστήματος χωρίζει τις πολιτισμικές συμβάσεις σε ανεξάρτητες κατηγορίες, καθεμία ονομασμένη LC_ ακολουθούμενο από την περιοχή που διέπει. Η ταξινόμηση (LC_COLLATE) είναι ξεχωριστή από τους κανόνες πεζών/κεφαλαίων (LC_CTYPE), που είναι ξεχωριστή από τη μορφοποίηση αριθμών (LC_NUMERIC), και ούτω καθεξής. Ένα locale είναι μια ονομασμένη δέσμη ρυθμίσεων - de_DE.UTF-8, sv_SE.UTF-8, C - και η μετάβαση σε αυτό μπορεί να αλλάξει όλες τις κατηγορίες ταυτόχρονα ή μόνο εκείνες που επιλέγετε. Οι κατηγορίες που τιμά η PetaPerl παρατίθενται στον πίνακα κατηγοριών παρακάτω.

Η pragma use locale#

Η συμπεριφορά που εξαρτάται από το locale είναι απενεργοποιημένη εξ ορισμού και έχει λεξιλογική εμβέλεια. Το use locale την ενεργοποιεί από εκείνο το σημείο μέχρι το τέλος του περικλείοντος μπλοκ (ή αρχείου)· το no locale την απενεργοποιεί ξανά για το υπόλοιπο της δικής του εμβέλειας. Τίποτα εκτός της λεξιλογικής εμβέλειας δεν επηρεάζεται - ένα άρθρωμα που δεν δηλώνει use locale διατηρεί την προεπιλεγμένη συμπεριφορά του locale C ακόμη και όταν καλείται από κώδικα που το δήλωσε.

use locale;                  # locale-aware from here down
my @sorted = sort @words;    # collates per LC_COLLATE
{
    no locale;               # back to codepoint order in this block
    my @plain = sort @words;
}

Χωρίς την pragma, τα sort, lc, uc, printf και τα υπόλοιπα χρησιμοποιούν σταθερούς κανόνες του locale C ανεξάρτητα από το τι λέει το περιβάλλον. Αυτή είναι μια σκόπιμη προεπιλογή ασφαλείας: ένα πρόγραμμα παράγει την ίδια έξοδο σε κάθε μηχάνημα μέχρι να ζητήσει ρητά να ακολουθήσει τις τοπικές συμβάσεις.

Η pragma ορίζει μια υπόδειξη ανά εντολή, ακριβώς όπως κάνει η upstream Perl, ώστε ένα μόνο αρχείο να μπορεί να αναμειγνύει ελεύθερα περιοχές με επίγνωση locale και περιοχές που το αγνοούν. Η ρύθμιση ταξιδεύει με τη λεξιλογική εμβέλεια, όχι με τη στοίβα κλήσεων.

Κατηγορίες locale#

Κάθε κατηγορία ελέγχει μια ξεχωριστή ομάδα λειτουργιών. Το use locale τις ενεργοποιεί όλες ταυτόχρονα· επιλέγετε ποιο locale είναι ενεργό ανά κατηγορία μέσω της setlocale. Η στήλη «επηρεαζόμενες λειτουργίες» συνδέει με τις σελίδες αναφοράς όπου η συμπεριφορά τεκμηριώνεται πλήρως - εκεί βρίσκονται οι κανόνες που εξαρτώνται από το locale για κάθε ενσωματωμένη συνάρτηση.

Κατηγορία

Διέπει

Επηρεαζόμενες λειτουργίες

LC_COLLATE

Σειρά ταξινόμησης και σύγκριση συμβολοσειρών

sort, οι συγκρίσεις συμβολοσειρών lt le gt ge cmp

LC_CTYPE

Ταξινόμηση χαρακτήρων και αντιστοίχιση πεζών/κεφαλαίων

lc, uc, lcfirst, ucfirst, \w \d \s και \b σε regex

LC_NUMERIC

Υποδιαστολή και ομαδοποίηση ψηφίων

printf, sprintf, μετατροπή αριθμού σε συμβολοσειρά

LC_MONETARY

Συμβάσεις μορφοποίησης νομίσματος

localeconv (μόνο επιθεώρηση· καμία ενσωματωμένη συνάρτηση δεν μορφοποιεί νομισματικά ποσά για εσάς)

LC_TIME

Ονόματα ημερών και μηνών, διάταξη ημερομηνίας

strftime μέσω POSIX, langinfo

LC_MESSAGES

Γλώσσα των συμβολοσειρών σφαλμάτων του συστήματος

κείμενο της $!, συμβολοσειρές μηνυμάτων της langinfo

Το LC_ALL δεν είναι μια ξεχωριστή κατηγορία αλλά μια συντομογραφία που ορίζει κάθε κατηγορία ταυτόχρονα.

Σημειώστε μια ασυμμετρία που μπερδεύει τον κόσμο: το LC_NUMERIC αλλάζει το πώς οι αριθμοί μορφοποιούνται για έξοδο, αλλά ο ίδιος ο πηγαίος κώδικας της Perl και η αριθμητική ανάλυσή της χρησιμοποιούν πάντα . ως διαχωριστή υποδιαστολής. Ένα script που διαβάζει 12,5 από ένα αρχείο γερμανικού locale χρειάζεται ακόμη να μεταφράσει το ίδιο το κόμμα προτού το χειριστεί ως αριθμό - το locale δεν κάνει το "12,5" + 0 να αποδίδει 12.5. Δείτε αριθμοί και συμβολοσειρές.

Ορισμός του locale#

Το use locale λέει ακολούθησε το locale· δεν λέει ποιο. Αυτή η επιλογή προέρχεται εξ ορισμού από το περιβάλλον, και μπορείτε να την ερωτήσετε ή να την παρακάμψετε μέσω του αρθρώματος POSIX.

Η setlocale επιλέγει το ενεργό locale για μια κατηγορία. Η ιδιωματική κλήση τιμά το περιβάλλον του χρήστη (LANG, LC_*):

use POSIX qw(setlocale LC_ALL LC_COLLATE);
setlocale(LC_ALL, "");                 # adopt the environment's locale
my $cur = setlocale(LC_COLLATE);       # query the active collation
setlocale(LC_COLLATE, "sv_SE.UTF-8");  # force one explicitly

Η localeconv επιστρέφει έναν hash που περιγράφει τις ενεργές συμβάσεις LC_NUMERIC και LC_MONETARY - την υποδιαστολή, τον διαχωριστή χιλιάδων, το σύμβολο νομίσματος και τα υπόλοιπα - ώστε ένα πρόγραμμα να μπορεί να μορφοποιεί τιμές μόνο του όταν καμία ενσωματωμένη συνάρτηση δεν το κάνει απευθείας.

Το I18N::Langinfo εκθέτει την langinfo, η οποία διαβάζει μεμονωμένα στοιχεία από το τρέχον locale: το τοπικοποιημένο όνομα μιας ημέρας της εβδομάδας ή ενός μήνα (DAY_1, MON_1), τη συμβολοσειρά μορφής ημερομηνίας, τον χαρακτήρα βάσης αρίθμησης, το σύμβολο νομίσματος. Είναι ο στενός συνοδός της localeconv, ένα στοιχείο τη φορά.

Locale και Unicode#

Η διαχείριση locale και το Unicode είναι δύο διαφορετικές απαντήσεις στο «τι είναι ένας χαρακτήρας», και αλληλεπιδρούν με τρόπους που αξίζει να κατανοήσετε προτού τα συνδυάσετε. Η πλήρης πραγμάτευση - πώς συντίθενται το use utf8, τα layers I/O UTF-8 και οι κανόνες LC_CTYPE του locale, και οι παγίδες που προκύπτουν όταν διαφωνούν - βρίσκεται στον οδηγό εκμάθησης Unicode. Ξεκινήστε με τις συμβολοσειρές και κωδικοποιήσεις Unicode και το κεφάλαιο των παγίδων· το κεφάλαιο regex και ιδιοτήτων καλύπτει το πώς συμπεριφέρονται το \w και οι κλάσεις χαρακτήρων υπό κάθε μοντέλο.

Διαρροές locale και ασφάλεια#

Ένα locale είναι καθολική κατάσταση επιπέδου διεργασίας στην υποκείμενη βιβλιοθήκη C, οπότε μια κλήση setlocale που γίνεται οπουδήποτε αλλάζει το locale παντού μέσα στη διεργασία - πέρα από τα όρια των αρθρωμάτων, όχι μόνο στην εμβέλεια που την κάλεσε. Δύο συνέπειες προκύπτουν:

  • Το use locale είναι ασφαλές ως προς την εμβέλεια· το setlocale δεν είναι. Η pragma είναι λεξιλογική και δεν διαρρέει τίποτα. Μια κλήση setlocale είναι μια καθολική παρενέργεια - αν μια βιβλιοθήκη ορίσει το LC_NUMERIC σε ένα locale με κόμμα ως υποδιαστολή και ξεχάσει να το επαναφέρει, κάθε μεταγενέστερο printf στο πρόγραμμα επηρεάζεται. Αποθηκεύστε και επαναφέρετε γύρω από μια προσωρινή αλλαγή:

    my $saved = setlocale(LC_NUMERIC);
    setlocale(LC_NUMERIC, "de_DE.UTF-8");
    # ... locale-sensitive work ...
    setlocale(LC_NUMERIC, $saved);
    
  • Τα μη έμπιστα ονόματα locale είναι μη έμπιστη είσοδος. Το να περνάτε μια συμβολοσειρά που παρέχεται από το περιβάλλον κατευθείαν στην setlocale επιτρέπει στο περιβάλλον να κατευθύνει τη μορφοποίηση του προγράμματός σας. Σε ένα ευαίσθητο ως προς την ασφάλεια περιβάλλον, επικυρώστε το όνομα ή καθηλώστε ρητά το locale αντί να καλείτε setlocale(LC_ALL, "").

Παράλληλη εκτέλεση και locale#

Η PetaPerl παραλληλοποιεί αυτόματα ορισμένους αριθμητικούς βρόχους σε νήματα εργασίας. Αυτό δεν επηρεάζει ποτέ κώδικα που εξαρτάται από το locale, εκ κατασκευής. Οι λειτουργίες των οποίων τα αποτελέσματα εξαρτώνται από το τρέχον locale - sort με την προεπιλεγμένη συνταξιοθεσία, σύγκριση συμβολοσειρών LC_COLLATE, αναδίπλωση πεζών/κεφαλαίων lc/uc/fc και μορφοποίηση αριθμών LC_NUMERIC - δεν μεταγλωττίζονται ποτέ με JIT ούτε παραλληλοποιούνται αυτόματα· εκτελούνται πάντα σειριακά στον διερμηνευτή έναντι του μοναδικού locale που ισχύει σε όλη τη διεργασία. Η αυτόματη παραλληλοποίηση εκτελεί πάντα μόνο σώματα αριθμητικών βρόχων, οπότε καμία εξαρτώμενη από το locale υπολογιστική εργασία δεν αποστέλλεται σε νήματα εργασίας. Δεν χρειάζεται να προστατεύετε την κατάσταση locale όταν γράφετε παραλληλοποιήσιμο κώδικα: η παράλληλη διαδρομή απλώς δεν την αγγίζει ποτέ.

Μεταβλητές περιβάλλοντος#

Όταν ένα πρόγραμμα καλεί setlocale(LC_ALL, ""), η βιβλιοθήκη C διαβάζει το locale από το περιβάλλον με μια σταθερή σειρά προτεραιότητας: το LC_ALL παρακάμπτει κάθε μεμονωμένη μεταβλητή LC_*, κάθε μεταβλητή LC_* ορίζει τη δική της κατηγορία, και το LANG παρέχει την προεπιλογή για κάθε κατηγορία που δεν ονομάζεται διαφορετικά. Αυτές οι μεταβλητές βρίσκονται στο %ENV όπως κάθε άλλη τιμή περιβάλλοντος, ώστε ένα πρόγραμμα να μπορεί να τις επιθεωρήσει ή να τις προσαρμόσει πριν από την κλήση setlocale που τις καταναλώνει.

Μεταβλητή

Αποτέλεσμα

LC_ALL

Παρακάμπτει όλες τις κατηγορίες

LC_COLLATE, LC_CTYPE, …

Ορίζει μία ονομασμένη κατηγορία

LANG

Προεπιλογή για κάθε κατηγορία που δεν ορίζεται παραπάνω

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

  • Μόνο Linux, εγγενώς UTF-8. Η PetaPerl τρέχει μόνο σε Linux έναντι των locale της βιβλιοθήκης C του συστήματος. Ο μηχανισμός locale ειδικός ανά πλατφόρμα που κουβαλά η upstream Perl για VMS, Windows και Android - τα shims locale του Win32::, οι ιδιοτροπίες κατηγοριών του VMS, οι εφεδρείες «τα locale δεν είναι διαθέσιμα σε αυτή την πλατφόρμα» - δεν έχει αντίστοιχο εδώ και απλώς απουσιάζει. Υπάρχει ένα μοντέλο locale: εκείνο του POSIX που παρέχει η glibc σας.

  • LC_NUMERIC και ανάλυση πηγαίου κώδικα. Όπως στην upstream, ο διαχωριστής υποδιαστολής που χρησιμοποιείται όταν η Perl αναλύει αριθμητικά κυριολεκτικά και μετατροπές συμβολοσειράς σε αριθμό είναι πάντα ., ανεξάρτητα από το locale· μόνο η μορφοποίηση της εξόδου σέβεται το LC_NUMERIC. Η PetaPerl δεν κάνει καμία εξαίρεση σε αυτό.

  • Η αυτόματη παραλληλοποίηση δεν αγγίζει ποτέ κώδικα που εξαρτάται από το locale. Η PetaPerl παραλληλοποιεί αυτόματα ορισμένους αριθμητικούς βρόχους σε νήματα εργασίας, μια δυνατότητα που η upstream Perl δεν διαθέτει. Επειδή οι λειτουργίες που εξαρτώνται από το locale (συνταξιοθεσία, αναδίπλωση πεζών/κεφαλαίων, μορφοποίηση αριθμών) δεν μεταγλωττίζονται ποτέ με JIT ούτε παραλληλοποιούνται, εκτελούνται πάντα σειριακά έναντι του μοναδικού locale που ισχύει σε όλη τη διεργασία - οπότε η δυνατότητα δεν εισάγει κανένα δικό της ζήτημα ασφάλειας locale. Δείτε Παράλληλη εκτέλεση και locale παραπάνω.

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

  • perlfunc - οι ενσωματωμένες συναρτήσεις των οποίων τη συμπεριφορά αλλάζει το locale: sort, lc, uc, lcfirst, ucfirst, sprintf, printf.

  • perlop - οι τελεστές σύγκρισης συμβολοσειρών (lt, cmp, …) που ταξινομούν υπό το LC_COLLATE.

  • perlvar - το %ENV περιέχει τις μεταβλητές LANG/LC_*· το $! φέρει κείμενο σφάλματος μεταφρασμένο σύμφωνα με το locale.

  • POSIX - οι setlocale και localeconv, η διεπαφή για την επιλογή και την επιθεώρηση του ενεργού locale.

  • I18N::Langinfo - η langinfo, για την ανάγνωση ενός τοπικοποιημένου στοιχείου (όνομα μήνα, χαρακτήρα βάσης αρίθμησης) τη φορά.

  • Συμβολοσειρές και κωδικοποιήσεις Unicode

    • πώς σχετίζεται το μοντέλο χαρακτήρων Unicode με το LC_CTYPE του locale.