Όριο μήκους αναγνωριστικών (Identifier too long)#
Διατύπωση του upstream#
Το perl5-upstream/pod/perlvar.pod αναφέρει, στην ενότητα Syntax of Variable Names:
Variable names in Perl can have several formats. Usually, they must begin with a letter or underscore, in which case they can be arbitrarily long (up to an internal limit of 251 characters) and may contain letters, digits, underscores, or the special sequence
::or'.
Αυτή η διατύπωση είναι παραπλανητική σε δύο σημεία.
Διόρθωση#
Η σωστή διατύπωση, για την σταθερή σειρά Perl 5.42, είναι:
Τα αναγνωριστικά μπορούν να έχουν μήκος έως 251 bytes. Ονόματα που υπερβαίνουν αυτό το μήκος προκαλούν σφάλμα κατά την ανάλυση:
Identifier too long.
Δύο πράγματα προκύπτουν από αυτό:
Bytes, όχι χαρακτήρες. Το όριο μετράται σε bytes της αναπαράστασης πηγής, όχι σε σημεία κώδικα Unicode. Τα αναγνωριστικά UTF-8 φτάνουν επομένως το όριο σε λιγότερους χαρακτήρες:
Πλάτος χαρακτήρα
Τελευταίο αποδεκτό
Πρώτο απορριπτέο
1 byte (ASCII)
251 χαρακτήρες
252 χαρακτήρες
2 bytes (π.χ.
é)125 χαρακτήρες
126 χαρακτήρες
3 bytes (π.χ.
ㄚ)83 χαρακτήρες
84 χαρακτήρες
4 bytes (π.χ.
𐌰- Γοτθικό)62 χαρακτήρες
63 χαρακτήρες
Σε κάθε περίπτωση η απόρριψη συμβαίνει όταν το μήκος σε bytes υπερβεί για πρώτη φορά τα 251. Οι «251 χαρακτήρες» του κειμένου του upstream είναι σωστοί μόνο για την περίπτωση ASCII.
Σκληρό σφάλμα, όχι «εσωτερικό όριο». Η διατύπωση «up to an internal limit» υπαινίσσεται κάτι ήπιο. Δεν είναι - ο αναλυτής του perl5 εγείρει μοιραία εξαίρεση
Identifier too long. Το μήνυμα είναι το μόνο που βλέπει ο χρήστης· δεν υπάρχει αποκοπή, προειδοποίηση ή εφεδρική συμπεριφορά.
Η άμεση αιτία στην 5.42 είναι ο ενταμιευτής tokenbuf[256] στην κατάσταση του αναλυτή, σε συνδυασμό με το e = dest_end - 3 (byte sigil + τελικό \0 + περιθώριο ασφαλείας) που υπολογίζεται μέσα στην S_parse_ident. Ο συνδυασμός δίνει 252 bytes συνολικά ÷ αφαιρώντας το sigil = 251 bytes καθαρού ονόματος αναγνωριστικού.
Το blead του upstream έχει ήδη ανεβάσει το όριο#
Ανεξάρτητα από αυτό το errata, η ανάπτυξη του perl5 (μετά την 5.42) έχει ήδη ανεβάσει το όριο. Το commit 8785c114b5 («parser.h Allow up to 256 characters in a token»), που εμφανίζεται για πρώτη φορά στο tag ανάπτυξης v5.43.4, αντικαθιστά το tokenbuf των 256 bytes με ενταμιευτή 1024 bytes. Η επόμενη σταθερή σειρά (Perl 5.44) αναμένεται επομένως να επιτρέπει αναγνωριστικά έως περίπου 1020 bytes από προεπιλογή. Το όριο των 251 bytes είναι χαρακτηριστικό της 5.42 και παλαιότερων.
pperl behavior#
pperl is the c2rust transpilation of perl5’s C interpreter. Its identifier-length behavior is:
Μήκος | perl5 5.42.2 | pperl |
|---|---|---|
251 bytes | αποδοχή | αποδοχή |
252 bytes | απόρριψη | αποδοχή (απόκλιση) |
1019 bytes | απόρριψη | αποδοχή (απόκλιση) |
1020 bytes | απόρριψη | απόρριψη |
1024 bytes | απόρριψη | απόρριψη |
Η απόκλιση είναι πραγματική και ορατή στον κώδικα του χρήστη. Η αιτία δεν βρίσκεται στην ίδια τη μεταγλώττιση μέσω c2rust. Η έξοδος του c2rust είναι πιστός, γραμμή προς γραμμή, καθρέφτης του πηγαίου C που δίνεται. Η αιτία είναι η μετατόπιση του upstream-checkout: το perl5-upstream/ είναι αυτή τη στιγμή καρφιτσωμένο σε στιγμιότυπο blead (μετά την 5.43.4) και όχι σε ετικέτα συντήρησης 5.42.x. Το blead έχει το ανεβασμένο tokenbuf - ο καθρέφτης του c2rust το κληρονομεί.
This is an instance of a broader category of latent divergences: upstream blead has accumulated 140+ commits to toke.c alone since the 5.42.2 tag, and the same arithmetic - whatever blead does is what pperl does - applies to every one of them. Other likely-affected areas (parser-visible only):
Το βελτιωμένο
qr/.../xx(PPC 0026) προσγειώνεται στο blead· ο χειρισμός κενών/σχολίων μέσα στις κλάσεις χαρακτήρων διαφέρει από την 5.42.intuit_morebug fixes (multiple commits): edge cases in$foo[bar]vs$foo{bar}ambiguity resolution behave better in pperl than in 5.42.Επανεγγραφή του API της
S_parse_ident: η θέση σφάλματος που αναφέρεται για τα σφάλματα ανάλυσης που σχετίζονται με αναγνωριστικά μετακινήθηκε ανάμεσα στην 5.42 και το blead.
Η αποκατάσταση δεν είναι να μπαλωθεί η έξοδος του c2rust· είναι να καρφιτσωθεί το perl5-upstream/ στο v5.42.2 και να επανεκτελεστεί ο αγωγός μεταγλώττισης.
Until that is done, pperl is - strictly speaking - «perl5 next» rather than «perl5 5.42 stable». For most user code this is invisible; for the corner cases above, behavior matches blead, not 5.42.
Τεστ#
Τα τεστ συμμόρφωσης που καλύπτουν αυτό το errata βρίσκονται στα:
t/01-parsing/090-identifier-length-ascii.tt/01-parsing/091-identifier-length-utf8.t
They probe the boundary at 251 bytes (ASCII and 2/3/4-byte UTF-8) and at the upstream-blead secondary cutoff near 1024 bytes. Each subtest encodes a perl5 5.42 expectation; pperl currently fails subsets of the suite as documented above. The failing subtests are the operational tracking record for this errata entry.