# Διαχείριση 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 ακόμη και όταν καλείται από κώδικα που το δήλωσε. ```perl 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`](../POSIX/setlocale.md). Η στήλη «επηρεαζόμενες λειτουργίες» συνδέει με τις σελίδες αναφοράς όπου η συμπεριφορά τεκμηριώνεται πλήρως - εκεί βρίσκονται οι κανόνες που εξαρτώνται από το locale για κάθε ενσωματωμένη συνάρτηση. | Κατηγορία | Διέπει | Επηρεαζόμενες λειτουργίες | |---------------|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| | `LC_COLLATE` | Σειρά ταξινόμησης και σύγκριση συμβολοσειρών | [`sort`](perlfunc/sort.md), οι συγκρίσεις συμβολοσειρών [`lt` `le` `gt` `ge` `cmp`](perlop.md) | | `LC_CTYPE` | Ταξινόμηση χαρακτήρων και αντιστοίχιση πεζών/κεφαλαίων | [`lc`](perlfunc/lc.md), [`uc`](perlfunc/uc.md), [`lcfirst`](perlfunc/lcfirst.md), [`ucfirst`](perlfunc/ucfirst.md), `\w` `\d` `\s` και `\b` σε regex | | `LC_NUMERIC` | Υποδιαστολή και ομαδοποίηση ψηφίων | [`printf`](perlfunc/printf.md), [`sprintf`](perlfunc/sprintf.md), [μετατροπή αριθμού σε συμβολοσειρά](perldata/numeric-strings.md) | | `LC_MONETARY` | Συμβάσεις μορφοποίησης νομίσματος | [`localeconv`](../POSIX/localeconv.md) (μόνο επιθεώρηση· καμία ενσωματωμένη συνάρτηση δεν μορφοποιεί νομισματικά ποσά για εσάς) | | `LC_TIME` | Ονόματα ημερών και μηνών, διάταξη ημερομηνίας | `strftime` μέσω [`POSIX`](../POSIX.md), [`langinfo`](../I18N/Langinfo.md) | | `LC_MESSAGES` | Γλώσσα των συμβολοσειρών σφαλμάτων του συστήματος | κείμενο της [`$!`](perlvar/error.md), συμβολοσειρές μηνυμάτων της [`langinfo`](../I18N/Langinfo.md) | Το `LC_ALL` δεν είναι μια ξεχωριστή κατηγορία αλλά μια συντομογραφία που ορίζει κάθε κατηγορία ταυτόχρονα. Σημειώστε μια ασυμμετρία που μπερδεύει τον κόσμο: το `LC_NUMERIC` αλλάζει το πώς οι αριθμοί *μορφοποιούνται για έξοδο*, αλλά ο ίδιος ο πηγαίος κώδικας της Perl και η αριθμητική *ανάλυσή* της χρησιμοποιούν πάντα `.` ως διαχωριστή υποδιαστολής. Ένα script που διαβάζει `12,5` από ένα αρχείο γερμανικού locale χρειάζεται ακόμη να μεταφράσει το ίδιο το κόμμα προτού το χειριστεί ως αριθμό - το locale δεν κάνει το `"12,5" + 0` να αποδίδει `12.5`. Δείτε [αριθμοί και συμβολοσειρές](perldata/numeric-strings.md). ## Ορισμός του locale Το `use locale` λέει *ακολούθησε το locale*· δεν λέει *ποιο*. Αυτή η επιλογή προέρχεται εξ ορισμού από το περιβάλλον, και μπορείτε να την ερωτήσετε ή να την παρακάμψετε μέσω του αρθρώματος `POSIX`. Η [`setlocale`](../POSIX/setlocale.md) επιλέγει το ενεργό locale για μια κατηγορία. Η ιδιωματική κλήση τιμά το περιβάλλον του χρήστη (`LANG`, `LC_*`): ```perl 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`](../POSIX/localeconv.md) επιστρέφει έναν hash που περιγράφει τις ενεργές συμβάσεις `LC_NUMERIC` και `LC_MONETARY` - την υποδιαστολή, τον διαχωριστή χιλιάδων, το σύμβολο νομίσματος και τα υπόλοιπα - ώστε ένα πρόγραμμα να μπορεί να μορφοποιεί τιμές μόνο του όταν καμία ενσωματωμένη συνάρτηση δεν το κάνει απευθείας. Το [`I18N::Langinfo`](../I18N/Langinfo.md) εκθέτει την `langinfo`, η οποία διαβάζει μεμονωμένα στοιχεία από το τρέχον locale: το τοπικοποιημένο όνομα μιας ημέρας της εβδομάδας ή ενός μήνα (`DAY_1`, `MON_1`), τη συμβολοσειρά μορφής ημερομηνίας, τον χαρακτήρα βάσης αρίθμησης, το σύμβολο νομίσματος. Είναι ο στενός συνοδός της `localeconv`, ένα στοιχείο τη φορά. ## Locale και Unicode Η διαχείριση locale και το Unicode είναι δύο διαφορετικές απαντήσεις στο «τι είναι ένας χαρακτήρας», και αλληλεπιδρούν με τρόπους που αξίζει να κατανοήσετε προτού τα συνδυάσετε. Η πλήρης πραγμάτευση - πώς συντίθενται το `use utf8`, τα layers I/O UTF-8 και οι κανόνες `LC_CTYPE` του locale, και οι παγίδες που προκύπτουν όταν διαφωνούν - βρίσκεται στον οδηγό εκμάθησης Unicode. Ξεκινήστε με τις [συμβολοσειρές και κωδικοποιήσεις Unicode](../../tutorial/unicode/strings-and-encodings.md) και το [κεφάλαιο των παγίδων](../../tutorial/unicode/pitfalls.md)· το [κεφάλαιο regex και ιδιοτήτων](../../tutorial/unicode/regex-and-properties.md) καλύπτει το πώς συμπεριφέρονται το `\w` και οι κλάσεις χαρακτήρων υπό κάθε μοντέλο. ## Διαρροές locale και ασφάλεια Ένα locale είναι καθολική κατάσταση επιπέδου διεργασίας στην υποκείμενη βιβλιοθήκη C, οπότε μια κλήση `setlocale` που γίνεται οπουδήποτε αλλάζει το locale παντού μέσα στη διεργασία - πέρα από τα όρια των αρθρωμάτων, όχι μόνο στην εμβέλεια που την κάλεσε. Δύο συνέπειες προκύπτουν: - **Το `use locale` είναι ασφαλές ως προς την εμβέλεια· το `setlocale` δεν είναι.** Η pragma είναι λεξιλογική και δεν διαρρέει τίποτα. Μια κλήση `setlocale` είναι μια καθολική παρενέργεια - αν μια βιβλιοθήκη ορίσει το `LC_NUMERIC` σε ένα locale με κόμμα ως υποδιαστολή και ξεχάσει να το επαναφέρει, κάθε μεταγενέστερο `printf` στο πρόγραμμα επηρεάζεται. Αποθηκεύστε και επαναφέρετε γύρω από μια προσωρινή αλλαγή: ```perl 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`](perlvar/args-env-inc.md) όπως κάθε άλλη τιμή περιβάλλοντος, ώστε ένα πρόγραμμα να μπορεί να τις επιθεωρήσει ή να τις προσαρμόσει πριν από την κλήση `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`](perlfunc.md) - οι ενσωματωμένες συναρτήσεις των οποίων τη συμπεριφορά αλλάζει το locale: `sort`, `lc`, `uc`, `lcfirst`, `ucfirst`, `sprintf`, `printf`. - [`perlop`](perlop.md) - οι τελεστές σύγκρισης συμβολοσειρών (`lt`, `cmp`, …) που ταξινομούν υπό το `LC_COLLATE`. - [`perlvar`](perlvar.md) - το `%ENV` περιέχει τις μεταβλητές `LANG`/`LC_*`· το `$!` φέρει κείμενο σφάλματος μεταφρασμένο σύμφωνα με το locale. - [`POSIX`](../POSIX.md) - οι `setlocale` και `localeconv`, η διεπαφή για την επιλογή και την επιθεώρηση του ενεργού locale. - [`I18N::Langinfo`](../I18N/Langinfo.md) - η `langinfo`, για την ανάγνωση ενός τοπικοποιημένου στοιχείου (όνομα μήνα, χαρακτήρα βάσης αρίθμησης) τη φορά. - [Συμβολοσειρές και κωδικοποιήσεις Unicode](../../tutorial/unicode/strings-and-encodings.md) - πώς σχετίζεται το μοντέλο χαρακτήρων Unicode με το `LC_CTYPE` του locale.