it-swarm.com.de

Warum vermeidet modernes Perl standardmäßig UTF-8?

Ich frage mich, warum die meisten modernen Lösungen, die mit Perl erstellt wurden, nicht standardmäßig TF-8 aktivieren.

Ich verstehe, dass es viele Legacy-Probleme bei Perl-Kernskripten gibt, bei denen es zu Problemen kommen kann. Aber aus meiner Sicht in der 21st Jahrhundert sollten große neue Projekte (oder Projekte mit einer großen Perspektive) ihre Software UTF-8 von Grund auf prüfen. Ich sehe es immer noch nicht. Zum Beispiel: Elch aktiviert strenge und Warnungen, aber nicht nicode . Modern :: Perl reduziert auch das Boilerplate, aber keine UTF-8-Behandlung.

Warum? Gibt es Gründe, UTF-8 in modernen Perl-Projekten im Jahr 2011 zu vermeiden?


Das Kommentieren von @tchrist ist zu lang geworden, daher füge ich es hier hinzu.

Es scheint, dass ich mich nicht klar ausgedrückt habe. Lassen Sie mich versuchen, einige Dinge hinzuzufügen.

tchrist und ich sehen die Situation ziemlich ähnlich, aber unsere Schlussfolgerungen sind völlig gegensätzlich. Ich stimme zu, die Situation mit Unicode ist kompliziert, aber aus diesem Grund benötigen wir (Perl-Benutzer und -Codierer) eine Schicht (oder ein Pragma), die die UTF-8-Handhabung so einfach macht, wie sie heutzutage sein muss.

tchrist wies auf viele zu behandelnde Aspekte hin, ich werde sie Tage oder sogar Wochen lang lesen und darüber nachdenken. Trotzdem ist das nicht mein Punkt. tchrist versucht zu beweisen, dass es keine einzige Möglichkeit gibt, "UTF-8 zu aktivieren". Ich habe nicht so viel Wissen, um damit zu streiten. Also halte ich mich an lebende Beispiele.

Ich habe mit Rakudo rumgespielt und UTF-8 war genau da , wie ich es brauchte . Ich hatte keine Probleme, es hat einfach funktioniert. Vielleicht gibt es irgendwo tiefere Einschränkungen, aber zu Beginn hat alles, was ich getestet habe, wie erwartet funktioniert.

Sollte das nicht auch in modernem Perl 5 ein Ziel sein? Ich betone es mehr: Ich schlage UTF-8 nicht als Standardzeichensatz für Core Perl vor, ich schlage die Möglichkeit vor, es mit einem Snap auszulösen für diejenigen, die neue Projekte entwickeln.

Ein anderes Beispiel, aber mit einem negativeren Ton. Frameworks sollen die Entwicklung erleichtern. Vor einigen Jahren habe ich Web-Frameworks ausprobiert, sie aber einfach weggeworfen, weil "Aktivieren von UTF-8" so dunkel war. Ich habe nicht gefunden, wie und wo Unicode-Unterstützung eingehängt werden kann. Es war so zeitaufwändig, dass ich es leichter fand, den alten Weg zu gehen. Jetzt habe ich hier gesehen, dass es eine Prämie gab, um das gleiche Problem mit Mason 2: Wie mache ich Mason2 UTF-8 sauber?. Es ist also ein ziemlich neues Framework, aber für die Verwendung mit UTF-8 sind fundierte Kenntnisse seiner Interna erforderlich. Es ist wie ein großes rotes Schild: STOP, benutze mich nicht!

Ich mag Perl wirklich. Der Umgang mit Unicode ist jedoch schmerzhaft. Ich renne immer noch gegen Wände. Irgendwie stimmt tchrist und beantwortet meine Fragen: Neue Projekte ziehen UTF-8 nicht an, weil es in Perl 5 zu kompliziert ist.

553
w.k

???? ??????????????????? ???? ???????? ??????????????? ???????????? ???????? ????????????????????????????? ???? ???????????? ????


??????????????? : ????????????????????????????? : ???? ????????????????????????????? ?????????????????????????????????????????? ??????????

  1. Setzen Sie Ihre Variable Perl_UNICODE Auf AS. Dadurch dekodieren alle Perl-Skripte @ARGV Als UTF-8-Zeichenfolgen und setzen die Kodierung aller drei Zeichenfolgen stdin, stdout und stderr auf UTF-8. Beides sind globale Effekte, keine lexikalischen.

  2. Stellen Sie ganz oben in Ihrer Quelldatei (Programm, Modul, Bibliothek, dohickey) sicher, dass Sie Perl Version 5.12 oder höher ausführen:

    use v5.12;  # minimal for unicode string feature
    use v5.14;  # optimal for unicode string feature
    
  3. Aktivieren Sie Warnungen, da die vorherige Deklaration nur Einschränkungen und Funktionen aktiviert, keine Warnungen. Ich schlage auch vor, Unicode-Warnungen in Ausnahmen umzuwandeln. Verwenden Sie also beide Zeilen und nicht nur eine davon. Beachten Sie jedoch, dass die Warnklasse utf8 Unter v5.14 drei weitere Unterwarnungen umfasst, die alle separat aktiviert werden können: nonchar, surrogate und non_unicode. Diese möchten Sie möglicherweise besser kontrollieren.

    use warnings;
    use warnings qw( FATAL utf8 );
    
  4. Deklarieren Sie, dass diese Quelleneinheit als UTF-8 codiert ist. Obwohl dieses Pragma einst andere Dinge tat, dient es jetzt nur noch diesem einen und keinem anderen Zweck:

    use utf8;
    
  5. Deklarieren Sie, dass alles, was ein Dateihandle öffnet in diesem lexikalischen Bereich, aber nicht anderswo, voraussetzt, dass dieser Stream in UTF-8 codiert ist, sofern Sie nichts anderes angeben. Auf diese Weise haben Sie keinen Einfluss auf den Code eines anderen Moduls oder Programms.

    use open qw( :encoding(UTF-8) :std );
    
  6. Aktivieren Sie benannte Zeichen mit \N{CHARNAME}.

    use charnames qw( :full :short );
    
  7. Wenn Sie ein DATA -Handle haben, müssen Sie die Codierung explizit festlegen. Wenn Sie möchten, dass dies UTF-8 ist, sagen Sie:

    binmode(DATA, ":encoding(UTF-8)");
    

Es gibt natürlich kein Ende von anderen Dingen, mit denen Sie sich möglicherweise irgendwann befassen werden, aber diese werden ausreichen, um das staatliche Ziel zu erreichen, dass „alles nur mit UTF-8 funktioniert“, auch wenn diese Begriffe etwas geschwächt sind.

Ein anderes Pragma, obwohl es nicht mit Unicode verwandt ist, ist:

      use autodie;

Es wird dringend empfohlen.


???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????


Zu sagen, dass Perl [ irgendwie ] Unicode standardmäßig aktivieren sollte, macht sich nicht einmal Gedanken darüber, genug zu sagen, um in irgendeiner Form auch nur marginal nützlich zu sein seltener und isolierter Fall. Unicode ist viel mehr als nur ein umfangreicheres Zeichenrepertoire. Es ist auch so, wie diese Charaktere auf viele, viele Arten interagieren.

Sogar die einfältigen minimalen Maßnahmen, die (einige) Menschen zu wollen scheinen, werden garantiert Millionen von Codezeilen durchbrechen, Code, der keine Chance hat, ein Upgrade auf Ihre schicke neue Welt durchzuführen Brave New World Moderne.

Es ist viel viel komplizierter, als die Leute vortäuschen. Ich habe in den letzten Jahren viel darüber nachgedacht. Mir würde gerne gezeigt werden, dass ich falsch liege. Aber ich glaube nicht, dass ich es bin. Unicode ist wesentlich komplexer als das Modell, das Sie ihm auferlegen möchten, und hier gibt es eine Komplexität, die Sie niemals unter den Teppich kehren können. Wenn Sie es versuchen, brechen Sie entweder Ihren eigenen Code oder den eines anderen. Irgendwann müssen Sie nur noch eine Pause einlegen und lernen, worum es bei Unicode geht. Sie können nicht so tun, als wäre es etwas, was es nicht ist.

???? macht Unicode so einfach wie nie zuvor. Wenn Sie der Meinung sind, dass dies schlecht ist, probieren Sie eine Weile etwas anderes aus. Dann komm zurück zu ????: Entweder bist du in eine bessere Welt zurückgekehrt, oder du bringst das gleiche Wissen mit, damit wir dein neues Wissen nutzen können, um ???? besser in diesen Dingen.


???? ??????????????????? ???????????? ???? ?????????????????????????? ⸗ ???????????????????? ???? ?????????????????????????? ??????????????? ????


Zumindest sind hier einige Dinge, die erforderlich zu sein scheinen für ???? So aktivieren Sie "Unicode standardmäßig":

  1. Alle ???? Der Quellcode sollte standardmäßig in UTF-8 sein. Sie erhalten dies mit use utf8 Oder export Perl5OPTS=-Mutf8.

  2. Das ???? DATA handle sollte UTF-8 sein. Sie müssen dies auf Paketbasis tun, wie in binmode(DATA, ":encoding(UTF-8)").

  3. Programm Argumente zu ???? Skripte sollten standardmäßig UTF-8 sein. export Perl_UNICODE=A Oder Perl -CA Oder export Perl5OPTS=-CA.

  4. Die Standardeingabe-, Ausgabe- und Fehlerströme sollten standardmäßig UTF-8 sein. export Perl_UNICODE=S Für alle von ihnen oder I, O und/oder E für nur einige von ihnen. Das ist wie Perl -CS.

  5. Alle anderen Griffe geöffnet von ???? sollte als UTF-8 betrachtet werden, sofern nicht anders angegeben; export Perl_UNICODE=D Oder mit i und o für bestimmte davon; export Perl5OPTS=-CD Würde funktionieren. Das macht -CSAD Für alle.

  6. Decken Sie beide Basen und alle Streams, die Sie öffnen, mit export Perl5OPTS=-Mopen=:utf8,:std Ab. Siehe einzigartig .

  7. Sie möchten UTF-8-Codierungsfehler nicht verpassen. Versuchen Sie export Perl5OPTS=-Mwarnings=FATAL,utf8. Und stellen Sie sicher, dass Ihre Eingabestreams immer binmoded bis :encoding(UTF-8) sind, nicht nur bis :utf8.

  8. Codepunkte zwischen 128 und 255 sollten verstanden werden von ???? die entsprechenden Unicode-Codepunkte sein, nicht nur nicht vergebene Binärwerte. use feature "unicode_strings" Oder export Perl5OPTS=-Mfeature=unicode_strings. Das ergibt uc("\xDF") eq "SS" und "\xE9" =~ /\w/. Ein einfacher export Perl5OPTS=-Mv5.12 Oder besser wird das auch bekommen.

  9. Benannte Unicode-Zeichen sind standardmäßig nicht aktiviert. Fügen Sie daher export Perl5OPTS=-Mcharnames=:full,:short,latin,greek Oder ein anderes hinzu. Siehe uninames und tcgrep .

  10. Sie benötigen fast immer Zugriff auf die Funktionen von dem Standardmodul Unicode::Normalize verschiedenen Arten von Zerlegungen. export Perl5OPTS=-MUnicode::Normalize=NFD,NFKD,NFC,NFKD, Und führen Sie eingehende und ausgehende Nachrichten von NFC immer über NFD aus. Es gibt noch keine E/A-Ebene für diese, die mir bekannt ist, aber siehe nfc , nfd , nfkd und nfkc .

  11. Zeichenkettenvergleiche in ???? Die Verwendung von eq, ne, lc, cmp, sort, & c & cc ist immer falsch. Anstelle von @a = sort @b Benötigen Sie also @a = Unicode::Collate->new->sort(@b). Könnte auch zu Ihrem export Perl5OPTS=-MUnicode::Collate Hinzugefügt werden. Sie können den Schlüssel für binäre Vergleiche zwischenspeichern.

  12. ???? Built-Ins wie printf und write machen das Falsche mit Unicode-Daten. Sie müssen das Unicode::GCString - Modul für das erstere und sowohl das als auch das Unicode::LineBreak - Modul für das letztere verwenden. Siehe uwc und unifmt .

  13. Wenn Sie möchten, dass sie als Ganzzahlen gezählt werden, müssen Sie Ihre \d+ - Captures durchlaufen lassen die Unicode::UCD::num - Funktion weil ???? in atoi (3) ist momentan nicht schlau genug.

  14. Sie werden Dateisystemprobleme auf haben ???? Dateisysteme. Einige Dateisysteme erzwingen stillschweigend eine Konvertierung in NFC. andere erzwingen stillschweigend eine Umstellung auf NFD. Und andere machen noch etwas anderes. Einige ignorieren die Angelegenheit sogar gänzlich, was zu noch größeren Problemen führt. Sie müssen also Ihr eigenes NFC/NFD-Handling durchführen, um gesund zu bleiben.

  15. All dein ???? Code mit a-z oder A-Z und dergleichen MUSS GEÄNDERT WERDEN , einschließlich m//, s/// und tr///. Es sollte als schreiende rote Fahne auffallen, dass Ihr Code kaputt ist. Es ist aber nicht klar, wie es sich ändern muss. Es ist schwieriger, die richtigen Eigenschaften zu finden und ihre Umstände zu verstehen, als Sie vielleicht denken. Ich benutze unichars und uniprops jeden Tag.

  16. Code, der \p{Lu} Verwendet, ist fast so falsch wie Code, der [A-Za-z] Verwendet. Sie müssen stattdessen \p{Upper} Verwenden und den Grund dafür kennen. Ja, \p{Lowercase} Und \p{Lower} Unterscheiden sich von \p{Ll} Und \p{Lowercase_Letter}.

  17. Code, der [a-zA-Z] Verwendet, ist noch schlimmer. Und es kann weder \pL Noch \p{Letter} Verwendet werden. Es muss \p{Alphabetic} verwendet werden. Nicht alle Buchstaben sind Buchstaben, wissen Sie!

  18. Wenn Sie suchen ???? Variablen mit /[\$\@\%]\w+/, dann haben Sie ein Problem. Sie müssen nach /[\$\@\%]\p{IDS}\p{IDC}*/ Suchen, und selbst das berücksichtigt keine Interpunktionsvariablen oder Paketvariablen.

  19. Wenn Sie nach Leerzeichen suchen, sollten Sie je nach Bedarf zwischen \h Und \v Wählen. Und Sie sollten niemals \s Verwenden, da es entgegen der landläufigen Meinung NICHT [\h\v] BEDEUTET.

  20. Wenn Sie \n Für eine Liniengrenze oder sogar \r\n Verwenden, machen Sie es falsch. Sie müssen \R Verwenden, was nicht dasselbe ist!

  21. Wenn Sie nicht wissen, wann und ob Sie nicode :: Stringprep aufrufen sollen, sollten Sie es besser lernen.

  22. Bei Vergleichen, bei denen die Groß-/Kleinschreibung nicht berücksichtigt wird, muss geprüft werden, ob zwei Dinge dieselben Buchstaben sind, unabhängig von ihren diakritischen Zeichen und dergleichen. Am einfachsten geht das mit dem Modul Standard Unicode :: Collate . Unicode::Collate->new(level => 1)->cmp($a, $b). Es gibt auch eq Methoden und solche, und Sie sollten wahrscheinlich auch etwas über die match und substr Methoden lernen. Diese haben deutliche Vorteile gegenüber den ???? eingebaute.

  23. Manchmal reicht das immer noch nicht aus, und Sie benötigen stattdessen das das Unicode :: Collate :: Locale -Modul, wie in Unicode::Collate::Locale->new(locale => "de__phonebook", level => 1)->cmp($a, $b). Bedenken Sie, dass Unicode::Collate::->new(level => 1)->eq("d", "ð") wahr ist, aber Unicode::Collate::Locale->new(locale=>"is",level => 1)->eq("d", " ð") falsch ist. In ähnlicher Weise sind "ae" und "æ" eq, wenn Sie keine Gebietsschemas verwenden, oder wenn Sie die englische verwenden, diese jedoch im isländischen Gebietsschema unterschiedlich sind. Was jetzt? Es ist schwer, sage ich dir. Sie können mit ucsort spielen, um einige dieser Dinge zu testen.

  24. Überlegen Sie, wie Sie das Muster CVCV (Konsonant, Vokal, Konsonant, Vokal) in der Zeichenfolge „ niño“ abgleichen. Die NFD-Form, an die Sie sich wohl besser erinnert hatten, lautet „nin\x {303} o“. Was wirst du jetzt tun? Selbst wenn Sie so tun, als wäre ein Vokal [aeiou] (Was übrigens falsch ist), können Sie so etwas nicht tun wie (?=[aeiou])\X), Weil selbst in NFD ein Codepunkt wie 'ø ' zerlegt nicht ! Mit dem UCA-Vergleich, den ich Ihnen gerade gezeigt habe, wird der Test jedoch gleich "o" sein. Sie können sich nicht auf NFD verlassen, sondern müssen sich auf UCA verlassen.


???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????


Und das ist nicht alles. Es gibt Millionen gebrochene Annahmen, die Menschen über Unicode machen. Bis sie diese Dinge verstehen, ihre ???? Code wird kaputt sein.

  1. Code, der davon ausgeht, dass er eine Textdatei öffnen kann, ohne dass die Codierung angegeben wird, ist fehlerhaft.

  2. Code, der davon ausgeht, dass die Standardcodierung eine fehlerhafte native Plattformcodierung ist.

  3. Code, der davon ausgeht, dass Webseiten in Japanisch oder Chinesisch in UTF-16 weniger Platz beanspruchen als in UTF-8, ist falsch.

  4. Code, der davon ausgeht, dass Perl UTF-8 intern verwendet, ist falsch.

  5. Code, der davon ausgeht, dass Codierungsfehler immer eine Ausnahme auslösen, ist falsch.

  6. Code, der davon ausgeht, dass Perl-Codepunkte auf 0x10_FFFF beschränkt sind, ist falsch.

  7. Code, der annimmt, dass Sie $/ Auf etwas setzen können, das mit jedem gültigen Zeilentrennzeichen funktioniert, ist falsch.

  8. Code, der die Gleichheit von Roundtrips in der Kasefaltung voraussetzt, wie lc(uc($s)) eq $s oder uc(lc($s)) eq $s, ist vollständig fehlerhaft und falsch. Bedenken Sie, dass die uc("σ") und uc("ς") beide "Σ" Sind, aber lc("Σ") möglicherweise nicht beide zurückgeben kann.

  9. Code, der davon ausgeht, dass jeder Codepunkt in Kleinbuchstaben einen eigenen Großbuchstaben enthält, oder umgekehrt, ist fehlerhaft. Beispiel: "ª" Ist ein Kleinbuchstabe ohne Großbuchstaben. Dabei sind sowohl "ᵃ" als auch "ᴬ" Buchstaben, jedoch keine Kleinbuchstaben. Beide sind jedoch Codepunkte in Kleinbuchstaben ohne entsprechende Großbuchstaben. Verstanden? Sie sind nicht \p{Lowercase_Letter}, Obwohl sie sowohl \p{Letter} Als auch \p{Lowercase} Sind.

  10. Code, bei dem davon ausgegangen wird, dass die Groß- und Kleinschreibung nicht geändert wird, ist fehlerhaft.

  11. Code, der davon ausgeht, dass nur zwei Fälle vorliegen, ist fehlerhaft. Es gibt auch eine Titelzeile.

  12. Code, der davon ausgeht, dass nur Buchstaben in Groß- und Kleinschreibung geschrieben werden, ist fehlerhaft. Es stellt sich heraus, dass nicht nur Buchstaben, sondern auch Zahlen, Symbole und gerade Zeichen Groß- und Kleinschreibung haben. Tatsächlich kann das Ändern der Groß-/Kleinschreibung sogar dazu führen, dass etwas seine allgemeine Hauptkategorie ändert, z. B. ein \p{Mark} In einen \p{Letter}. Es kann auch dazu führen, dass von einem Skript zu einem anderen gewechselt wird.

  13. Code, der davon ausgeht, dass die Groß- und Kleinschreibung niemals von der Ländereinstellung abhängig ist, ist fehlerhaft.

  14. Code, der davon ausgeht, dass Unicode eine Abbildung über POSIX-Gebietsschemas enthält, ist fehlerhaft.

  15. Code, der davon ausgeht, dass Sie diakritische Zeichen entfernen können, um an Basisbuchstaben ASCII zu gelangen, ist böse, immer noch gebrochen, hirngeschädigt, falsch und berechtigt zur Todesstrafe.

  16. Code, der davon ausgeht, dass diakritische Zeichen \p{Diacritic} Und Zeichen \p{Mark} Dasselbe sind, ist fehlerhaft.

  17. Code, der davon ausgeht, dass \p{GC=Dash_Punctuation} So viel abdeckt, wie \p{Dash} Kaputt ist.

  18. Code, der davon ausgeht, dass Bindestriche, Bindestriche und Minuszeichen dasselbe sind oder nur einer von beiden vorhanden ist, ist fehlerhaft und fehlerhaft.

  19. Code, der davon ausgeht, dass jeder Codepunkt nicht mehr als eine Druckspalte einnimmt, wird unterbrochen.

  20. Code, der davon ausgeht, dass alle \p{Mark} - Zeichen keine Druckspalten belegen, ist fehlerhaft.

  21. Code, der davon ausgeht, dass gleich aussehende Zeichen sind gleich sind, ist fehlerhaft.

  22. Code, der davon ausgeht, dass Zeichen, die nicht gleich aussehen, nicht gleich sind, ist fehlerhaft.

  23. Code, der davon ausgeht, dass die Anzahl der Codepunkte in einer Zeile begrenzt ist, mit denen nur ein \X Übereinstimmen kann, ist falsch.

  24. Code, der davon ausgeht, dass \X Niemals mit einem \p{Mark} - Zeichen beginnen kann, ist falsch.

  25. Code, der davon ausgeht, dass \X Niemals zwei Nicht - \p{Mark} - Zeichen enthalten kann, ist falsch.

  26. Code, der davon ausgeht, dass er nicht "\x{FFFF}" Verwenden kann, ist falsch.

  27. Code, der einen Nicht-BMP-Codepunkt voraussetzt, der zwei UTF-16-Codeeinheiten (Ersatzcodeeinheiten) erfordert, codiert in zwei separate UTF-8-Zeichen, eines pro Codeeinheit, ist falsch. Dies ist nicht der Fall: Es wird in einen einzelnen Codepunkt codiert.

  28. Code, der von UTF-16 oder UTF-32 mit führenden Stücklisten in UTF-8 umcodiert, ist fehlerhaft, wenn am Anfang des resultierenden UTF-8 eine Stückliste eingefügt wird. Das ist so dumm, wenn dem Ingenieur die Augenlider entfernt werden.

  29. Code, der davon ausgeht, dass CESU-8 eine gültige UTF-Codierung ist, ist falsch. Ebenso ist Code, der U + 0000 als "\xC0\x80" Codiert, UTF-8 und falsch. Diese Jungs verdienen auch die Augenlidbehandlung.

  30. Code, der davon ausgeht, dass Zeichen wie > Immer nach rechts und < Immer nach links zeigen, ist falsch - weil sie es tatsächlich nicht tun.

  31. Code, der annimmt, dass, wenn Sie zuerst das Zeichen X und dann das Zeichen Y ausgeben, diese als XY angezeigt werden, falsch ist. Manchmal tun sie es nicht.

  32. Code, der davon ausgeht, dass ASCII gut genug ist, um Englisch richtig zu schreiben, ist dumm, kurzsichtig, Analphabet, kaputt, böse und falsch. Mit den Köpfen ab! Wenn das zu extrem erscheint, können wir einen Kompromiss eingehen: Von nun an dürfen sie nur noch mit dem großen Zeh von einem Fuß aus tippen (der Rest ist noch gebückt).

  33. Code, der davon ausgeht, dass alle \p{Math} - Codepunkte sichtbare Zeichen sind, ist falsch.

  34. Code, der annimmt, dass \w Nur Buchstaben, Ziffern und Unterstriche enthält, ist falsch.

  35. Code, der davon ausgeht, dass ^ Und ~ Interpunktionszeichen sind, ist falsch.

  36. Code, der davon ausgeht, dass ü Einen Umlaut hat, ist falsch.

  37. Code, der glaubt, dass Dinge wie Buchstaben enthalten, ist falsch.

  38. Code, der glaubt, dass \p{InLatin} Dasselbe ist wie \p{Latin}, Ist abscheulich gebrochen.

  39. Code, der glaubt, dass \p{InLatin} Fast immer nützlich ist, ist mit ziemlicher Sicherheit falsch.

  40. Code, der glaubt, dass $FIRST_LETTER Als der erste Buchstabe eines Alphabets und $LAST_LETTER Als der letzte Buchstabe desselben Alphabets angegeben wird, dass [${FIRST_LETTER}-${LAST_LETTER}] Eine Bedeutung hat, die fast immer vollständig gebrochen ist und falsch und bedeutungslos.

  41. Code, der glaubt, dass der Name einer Person nur bestimmte Zeichen enthalten kann, ist dumm, anstößig und falsch.

  42. Code, der versucht, Unicode auf ASCII zu reduzieren, ist nicht nur falsch, sein Täter sollte niemals wieder in der Programmierung arbeiten dürfen. Zeitraum. Ich bin mir nicht einmal sicher, ob sie es noch einmal sehen dürfen, da es ihnen offensichtlich bisher nicht viel Gutes gebracht hat.

  43. Code, der glaubt, dass es eine Möglichkeit gibt, vorzutäuschen, dass keine Textdatei-Codierungen existieren, ist fehlerhaft und gefährlich. Könnte auch das andere Auge herausstechen.

  44. Code, der unbekannte Zeichen in ? Umwandelt, ist kaputt, dumm, rätselhaft und läuft der Standardempfehlung zuwider, die besagt , dass das nicht zu tun ist RTFM für warum nicht.

  45. Code, der glaubt, die Codierung einer nicht markierten Textdatei zuverlässig erraten zu können, ist schuld an einer tödlichen Mischung aus Hybris und Naivität, die nur ein Blitz von Zeus beheben kann.

  46. Code, der glaubt, dass Sie verwenden können ???? printf Breiten zum Auffüllen und Ausrichten von Unicode-Daten sind fehlerhaft und falsch.

  47. Code, der glaubt, dass Sie nach dem erfolgreichen Erstellen einer Datei mit einem bestimmten Namen diese Datei mit dem Namen finden, unter dem Sie sie erstellt haben, wenn Sie ls oder readdir in ihrem umschließenden Verzeichnis ausführen ist fehlerhaft, kaputt und falsch. Hör auf, davon überrascht zu sein!

  48. Code, der glaubt, UTF-16 sei eine Kodierung mit fester Breite, ist dumm, kaputt und falsch. Ihre Programmierlizenz widerrufen.

  49. Code, der Codepunkte von einer Ebene ein Whit anders als die von jeder anderen Ebene behandelt, ist ipso facto gebrochen und falsch. Zurück zur Schule gehen.

  50. Code, der glaubt, dass Dinge wie /s/i Nur mit "S" Oder "s" Übereinstimmen können, ist fehlerhaft und falsch. Du wärest überrascht.

  51. Code, der \PM\pM* Zum Auffinden von Graphemclustern anstelle von \X Verwendet, ist fehlerhaft und fehlerhaft.

  52. Menschen, die zurück in die ASCII - Welt wollen, sollten von ganzem Herzen dazu ermutigt werden, und zu Ehren ihres herrlichen Upgrades sollten sie gratis mit einem vorelektrischen Gerät ausgestattet werden manuelle Schreibmaschine für alle Dateneingabebedürfnisse. An sie gesendete Nachrichten sollten mit einem 40-stelligen Telegrafen pro Zeile gesendet und von einem Kurier per Hand zugestellt werden. HALT.


???? ???? ?????????????????????? ⸗ ????????????????????? ???????????? ?????????????????????????? ⸗ ??????????????????? ??????????????? ???? ????


Mein eigenes Kochfeld sieht heutzutage so aus:

use 5.014;

use utf8;
use strict;
use autodie;
use warnings; 
use warnings    qw< FATAL  utf8     >;
use open        qw< :std  :utf8     >;
use charnames   qw< :full >;
use feature     qw< unicode_strings >;

use File::Basename      qw< basename >;
use Carp                qw< carp croak confess cluck >;
use Encode              qw< encode decode >;
use Unicode::Normalize  qw< NFD NFC >;

END { close STDOUT }

if (grep /\P{ASCII}/ => @ARGV) { 
   @ARGV = map { decode("UTF-8", $_) } @ARGV;
}

$0 = basename($0);  # shorter messages
$| = 1;

binmode(DATA, ":utf8");

# give a full stack dump on any untrapped exceptions
local $SIG{__DIE__} = sub {
    confess "Uncaught exception: @_" unless $^S;
};

# now promote run-time warnings into stackdumped exceptions
#   *unless* we're in an try block, in which 
#   case just generate a clucking stackdump instead
local $SIG{__WARN__} = sub {
    if ($^S) { cluck   "Trapped warning: @_" } 
    else     { confess "Deadly warning: @_"  }
};

while (<>)  {
    chomp;
    $_ = NFD($_);
    ...
} continue {
    say NFC($_);
}

__END__

???? ???? ???? ???? ???? ???? ???? ???? ????


Ich weiß nicht, wie viel mehr "Standard-Unicode in ????" Sie erhalten können, als ich geschrieben habe. Nun ja, Sie sollten auch Unicode::Collate Und Unicode::LineBreak Verwenden. Und wahrscheinlich noch mehr.

Wie Sie sehen, gibt es viel zu viele Unicode-Dinge, um die Sie sich wirklich do kümmern müssen, damit ever solche Dinge wie "default to Unicode" existieren ”.

Was wirst du entdecken, so wie wir es damals getan haben ???? 5.8, dass es einfach unmöglich ist, all diese Dinge Code aufzuzwingen, der nicht von Anfang an entworfen wurde, um sie zu berücksichtigen. Ihre wohlmeinende Selbstsucht hat die ganze Welt zerstört.

Und selbst wenn Sie dies einmal tun, gibt es immer noch kritische Punkte, die viel Nachdenken erfordern, um richtig zu werden. Es gibt keinen Schalter, den Sie umlegen können. Nichts als Gehirn, und ich meine echtes Gehirn, wird hier ausreichen. Es gibt eine Menge Dinge, die Sie lernen müssen. Wenn Sie sich zur manuellen Schreibmaschine zurückziehen, können Sie einfach nicht hoffen, in Unwissenheit vorbeizukommen. Dies ist das 21. Jahrhundert, und Sie können Unicode nicht durch vorsätzliche Ignoranz hinwegwünschen.

Du musst es lernen. Zeitraum. Es wird niemals so einfach sein, dass „alles einfach funktioniert“, da dies garantiert, dass viele Dinge nicht funktionieren - was die Annahme, dass es jemals einen Weg geben kann, ungültig macht um "alles zum Laufen zu bringen".

Es kann sein, dass Sie für einige wenige und sehr eingeschränkte Vorgänge ein paar vernünftige Standardeinstellungen erhalten, aber nicht ohne viel mehr über die Dinge nachzudenken, als ich denke.

Als nur ein Beispiel wird das kanonische Ordnen einige echte Kopfschmerzen verursachen. ???? "\x{F5}" 'õ' , "o\x{303}" 'õ' , "o\x{303}\x{304}" 'ȭ' und "o\x{304}\x{303}" 'ō̃' sollten alle übereinstimmen 'õ' , aber wie in aller Welt wirst du das machen? Das ist schwieriger als es aussieht, aber es ist etwas, das Sie berücksichtigen müssen. ????

Wenn ich etwas über Perl weiß, ist es das, was seine Unicode-Bits tun und was nicht, und dieses Ding verspreche ich Ihnen: "̲ᴛ̲ʜ̲ᴇ̲ʀ̲ᴇ̲ ̲ᴛ̲ʜ̲ᴇ̲ʀ̲ᴇ̲s̲ɪ̲ ̲U̲ ̲ᴍ̲ᴀ̲ɢ̲ɪ̲ᴄ̲ ̲ʙ̲ᴜ̲ʟ̲ʟ̲ᴇ̲ᴛ̲ ̲" ? ???

Sie können nicht einfach einige Standardeinstellungen ändern und ein reibungsloses Segeln erreichen. Es ist wahr, dass ich renne ???? mit Perl_UNICODE auf "SA" gesetzt, aber das ist alles, und selbst das ist meistens für Befehlszeilen-Sachen. Für die eigentliche Arbeit gehe ich alle oben beschriebenen Schritte durch und mache es sehr, sehr sorgfältig.


???? ¡Ƨdləɥ ƨᴉɥʇ ədoɥ puɐ ʻλɐp əɔᴉu ɐ əʌɐɥ ʻəʌɐɥnl poo⅁ ????

1131
tchrist

Die Verarbeitung von Unicode-Text erfolgt in zwei Schritten. Die erste lautet: "Wie kann ich es eingeben und ausgeben, ohne Informationen zu verlieren?". Die zweite lautet "Wie behandle ich Text gemäß den Konventionen der Landessprache".

der Beitrag von tchrist deckt beides ab, aber im zweiten Teil stammen 99% des Textes in seinem Beitrag. Die meisten Programme verarbeiten E/A-Vorgänge nicht einmal richtig. Es ist daher wichtig, dass Sie dies verstehen, bevor Sie sich überhaupt um Normalisierung und Sortierung kümmern.

Dieser Beitrag zielt darauf ab, das erste Problem zu lösen

Wenn Sie Daten in Perl einlesen, ist es egal, um welche Codierung es sich handelt. Es reserviert etwas Speicher und steckt die Bytes dort weg. Wenn Sie print $str Sagen, werden nur diese Bytes an Ihrem Terminal ausgeblendet. Dies setzt wahrscheinlich voraus, dass alles, was darauf geschrieben wird, UTF-8 ist, und Ihr Text wird angezeigt.

Fabelhaft.

Nur ist es nicht so. Wenn Sie versuchen, die Daten als Text zu behandeln, werden Sie feststellen, dass etwas Schlimmes passiert. Sie müssen nicht weiter als length gehen, um festzustellen, was Perl von Ihrem String hält und was Sie von Ihrem String nicht halten. Schreiben Sie einen Einzeiler wie: Perl -E 'while(<>){ chomp; say length }' und geben Sie 文字化け Ein und Sie erhalten 12 ... nicht die richtige Antwort, 4.

Das liegt daran, dass Perl davon ausgeht, dass Ihre Zeichenfolge kein Text ist. Sie müssen ihm sagen, dass es Text ist, bevor er Ihnen die richtige Antwort gibt.

Das ist leicht genug; Das Encode-Modul hat die Funktionen, um dies zu tun. Der generische Einstiegspunkt ist Encode::decode (Oder natürlich use Encode qw(decode)). Diese Funktion nimmt eine Zeichenfolge von der Außenwelt (was wir "Oktette" nennen, eine Art "8-Bit-Bytes" zu sagen) und verwandelt sie in einen Text, den Perl verstehen wird. Das erste Argument ist ein Zeichencodierungsname wie "UTF-8" oder "ASCII" oder "EUC-JP". Das zweite Argument ist die Zeichenfolge. Der Rückgabewert ist der Perl-Skalar, der den Text enthält.

(Es gibt auch Encode::decode_utf8, Das für die Codierung UTF-8 voraussetzt.)

Wenn wir unseren Einzeiler umschreiben:

Perl -MEncode=decode -E 'while(<>){ chomp; say length decode("UTF-8", $_) }'

Wir tippen 文字 化 化 ein und erhalten als Ergebnis "4". Erfolg.

Genau das ist die Lösung für 99% der Unicode-Probleme in Perl.

Der Schlüssel ist, wann immer ein Text in Ihr Programm kommt, müssen Sie ihn dekodieren. Das Internet kann keine Zeichen übertragen. Dateien können keine Zeichen speichern. Ihre Datenbank enthält keine Zeichen. Es gibt nur Oktette und Sie können Oktette in Perl nicht als Zeichen behandeln. Sie müssen die codierten Oktette mit dem Encode-Modul in Perl-Zeichen decodieren.

Die andere Hälfte des Problems besteht darin, Daten aus Ihrem Programm abzurufen. Das ist einfach zu; Sagen Sie einfach use Encode qw(encode), entscheiden Sie, in welcher Codierung Ihre Daten vorliegen sollen (UTF-8 für Terminals, die UTF-8, UTF-16 für Dateien unter Windows usw. verstehen), und geben Sie dann das Ergebnis aus encode($encoding, $data) anstatt nur $data auszugeben.

Diese Operation konvertiert Perls Zeichen, mit denen Ihr Programm arbeitet, in Oktetts, die von der Außenwelt verwendet werden können. Es wäre viel einfacher, wenn wir nur Zeichen über das Internet oder an unsere Terminals senden könnten, aber wir können nicht: nur Oktette. Wir müssen also Zeichen in Oktette konvertieren, sonst sind die Ergebnisse undefiniert.

Zusammenfassend: Kodieren Sie alle Ausgänge und dekodieren Sie alle Eingänge.

Jetzt werden wir über drei Probleme sprechen, die dies zu einer kleinen Herausforderung machen. Das erste sind Bibliotheken. Gehen sie richtig mit Text um? Die Antwort ist ... sie versuchen es. Wenn Sie eine Webseite herunterladen, gibt LWP Ihr Ergebnis als Text zurück. Wenn Sie die richtige Methode für das Ergebnis aufrufen, ist das (und das ist zufällig decoded_content, Nicht content, was nur der Oktett-Stream ist, den er vom Server erhalten hat.) Datenbanktreiber können sei schuppig; Wenn Sie DBD :: SQLite nur mit Perl verwenden, funktioniert es, aber wenn ein anderes Tool Text in Ihre Datenbank geschrieben hat, der als eine andere Codierung als UTF-8 gespeichert ist, wird dies nicht richtig gehandhabt bis Sie Code schreiben, um es richtig zu behandeln.

Die Ausgabe von Daten ist normalerweise einfacher. Wenn Sie jedoch "Wide Character in Print" sehen, wissen Sie, dass Sie die Codierung irgendwo durcheinander bringen. Diese Warnung bedeutet: "Hey, Sie versuchen, Perl-Zeichen an die Außenwelt weiterzuleiten, und das ergibt keinen Sinn." Ihr Programm scheint zu funktionieren (weil das andere Ende normalerweise die rohen Perl-Zeichen korrekt behandelt), aber es ist sehr kaputt und könnte jeden Moment aufhören zu arbeiten. Beheben Sie dies mit einem expliziten Encode::encode!

Das zweite Problem ist UTF-8-codierter Quellcode. Sofern Sie nicht use utf8 Am Anfang jeder Datei angeben, geht Perl nicht davon aus, dass Ihr Quellcode UTF-8 ist. Dies bedeutet, dass Sie jedes Mal, wenn Sie etwas wie my $var = 'ほげ' Sagen, Müll in Ihr Programm injizieren, der alles schrecklich kaputt macht. Sie müssen nicht "utf8" verwenden, aber wenn Sie dies nicht tun, dürfen Sie müssen keine Nicht-ASCII-Zeichen in Ihrem Programm verwenden.

Das dritte Problem ist, wie Perl mit der Vergangenheit umgeht. Vor langer Zeit gab es kein Unicode, und Perl ging davon aus, dass es sich bei allem um Latin-1-Text oder Binärdateien handelte. Wenn also Daten in Ihr Programm gelangen und Sie beginnen, sie als Text zu behandeln, behandelt Perl jedes Oktett als lateinisches 1-Zeichen. Als wir nach der Länge von "文字 化 け" fragten, erhielten wir daher 12. Perl nahm an, dass wir die Latin-1-Zeichenfolge "æååã" (12 Zeichen, von denen einige nicht gedruckt werden) verwendeten.

Dies wird als "implizites Upgrade" bezeichnet, und es ist durchaus sinnvoll, dies zu tun, aber es ist nicht das, was Sie möchten, wenn Ihr Text nicht Latin-1 ist. Aus diesem Grund ist es wichtig, Eingaben explizit zu dekodieren: Wenn Sie dies nicht tun, wird Perl dies tun und es könnte auch falsch laufen.

Menschen geraten in Schwierigkeiten, wenn die Hälfte ihrer Daten eine ordnungsgemäße Zeichenfolge ist und einige weiterhin binär sind. Perl interpretiert den Teil, der noch binär ist, so, als ob es sich um Latin-1-Text handelt, und kombiniert ihn dann mit den richtigen Zeichendaten. Dadurch sieht es so aus, als ob der richtige Umgang mit Ihren Charakteren Ihr Programm zerstört hätte, aber in Wirklichkeit haben Sie es einfach nicht genug behoben.

Hier ein Beispiel: Sie haben ein Programm, das eine UTF-8-codierte Textdatei liest, Sie setzen einen Unicode PILE OF POO In jede Zeile und drucken ihn aus. Du schreibst es so:

while(<>){
    chomp;
    say "$_ ????";
}

Führen Sie dann einige UTF-8-codierte Daten aus, z.

Perl poo.pl input-data.txt

Es druckt die UTF-8-Daten mit einem Poo am Ende jeder Zeile. Perfekt, mein Programm funktioniert!

Aber nein, du machst nur binäre Verkettung. Sie lesen Oktette aus der Datei, entfernen ein \n Mit chomp und setzen dann die Bytes in der UTF-8-Darstellung des Zeichens PILE OF POO Fort. Wenn Sie Ihr Programm überarbeiten, um die Daten aus der Datei zu dekodieren und die Ausgabe zu kodieren, werden Sie bemerken, dass Sie anstelle des Poo Müll ("ð ©") erhalten. Dies führt Sie zu der Annahme, dass das Dekodieren der Eingabedatei falsch ist. Es ist nicht.

Das Problem ist, dass das Poo implizit als Latin-1 aktualisiert wird. Wenn Sie use utf8, Um den wörtlichen Text anstelle von binär zu machen, dann wird es wieder funktionieren!

(Das ist das größte Problem, das ich sehe, wenn ich Menschen mit Unicode helfe. Sie haben sich richtig verabschiedet und das hat ihr Programm kaputt gemacht. Das ist traurig an undefinierten Ergebnissen: Sie können ein Programm für eine lange Zeit haben, aber wenn Sie anfangen, es zu reparieren, Machen Sie sich keine Sorgen, wenn Sie Ihrem Programm Codierungs-/Decodierungsanweisungen hinzufügen und es bricht, bedeutet dies nur, dass Sie mehr Arbeit zu erledigen haben. Wenn Sie das nächste Mal von Anfang an an Unicode denken, wird dies der Fall sein viel einfacher!)

Das ist wirklich alles, was Sie über Perl und Unicode wissen müssen. Wenn Sie Perl mitteilen, um welche Daten es sich handelt, bietet Perl die beste Unicode-Unterstützung unter allen gängigen Programmiersprachen. Wenn Sie jedoch annehmen, dass es auf magische Weise weiß, welche Art von Text Sie einspeisen, werden Sie Ihre Daten unwiderruflich in den Papierkorb werfen. Nur weil Ihr Programm heute auf Ihrem UTF-8-Terminal funktioniert, heißt das nicht, dass es morgen auf einer UTF-16-codierten Datei funktioniert. Machen Sie es jetzt sicher und ersparen Sie sich den Kopfschmerz, die Daten Ihrer Benutzer zu vernichten!

Der einfache Teil des Umgangs mit Unicode ist das Codieren von Ausgaben und das Decodieren von Eingaben. Der schwierige Teil besteht darin, alle Ihre Ein- und Ausgaben zu finden und zu bestimmen, um welche Codierung es sich handelt. Aber das ist der Grund, warum du das große Geld bekommst :)

96
jrockway

Wir sind uns alle einig, dass es aus vielen Gründen ein schwieriges Problem ist, aber genau das ist der Grund, es allen leichter zu machen.

Es gibt ein aktuelles CPAN-Modul, tf8 :: all , das versucht, "Unicode einzuschalten. Alles davon".

Wie bereits erwähnt, können Sie nicht auf magische Weise dafür sorgen, dass das gesamte System (externe Programme, externe Webanforderungen usw.) auch Unicode verwendet. Wir können jedoch zusammenarbeiten, um sinnvolle Tools zu entwickeln, mit denen sich häufig auftretende Probleme leichter lösen lassen. Das ist der Grund, warum wir Programmierer sind.

Wenn utf8 :: all etwas nicht tut, von dem Sie denken, dass es es sollte, verbessern wir es, um es besser zu machen. Oder lassen Sie uns zusätzliche Tools erstellen, die zusammen den unterschiedlichen Bedürfnissen der Menschen so gut wie möglich entsprechen.

`

47
Randy Stauner

Ich denke, Sie verstehen Unicode und seine Beziehung zu Perl falsch. Unabhängig davon, auf welche Weise Sie Daten, Unicode, ISO-8859-1 oder viele andere Dinge speichern, muss Ihr Programm wissen, wie die Bytes interpretiert werden, die es als Eingabe (Decodierung) erhält, und wie die dargestellt werden Informationen, die ausgegeben werden sollen (Kodierung). Wenn Sie diese Interpretation falsch verstehen, verfälschen Sie die Daten. In Ihrem Programm gibt es keine magischen Standardeinstellungen, die den Mitarbeitern außerhalb Ihres Programms mitteilen, wie sie vorgehen sollen.

Sie denken, es ist höchstwahrscheinlich schwierig, weil Sie an alles gewöhnt sind, was ASCII ist. Alles, woran Sie hätten denken sollen, wurde von der Programmiersprache und all den Dingen, mit denen sie interagieren musste, einfach ignoriert. Wenn alles nur UTF-8 verwendet und Sie keine andere Wahl hätten, wäre UTF-8 genauso einfach. Aber nicht alles verwendet UTF-8. Sie möchten beispielsweise nicht, dass Ihr Eingabe-Handle den Eindruck erweckt, UTF-8-Oktette zu erhalten, es sei denn, dies ist tatsächlich der Fall, und Sie möchten nicht, dass Ihre Ausgabe-Handles UTF-8 sind, wenn das von ihnen gelesene Objekt UTF-8 verarbeiten kann . Perl hat keine Möglichkeit, diese Dinge zu wissen. Deshalb bist du der Programmierer.

Ich denke nicht, dass Unicode in Perl 5 zu kompliziert ist. Ich finde es unheimlich und die Leute meiden es. Es besteht ein Unterschied. Zu diesem Zweck habe ich Unicode eingefügt Perl lernen, 6. Ausgabe, und es gibt eine Menge Unicode-Zeug in Effektive Perl-Programmierung. Sie müssen sich die Zeit nehmen, um Unicode und seine Funktionsweise zu lernen und zu verstehen. Sie werden es sonst nicht effektiv nutzen können.

34
brian d foy

Wenn ich diesen Thread lese, habe ich oft den Eindruck, dass Leute " TF-8 " als Synonym für " nicode " verwenden. Bitte unterscheiden Sie zwischen den "Code-Points" von Unicode, die ein vergrößerter Verwandter des ASCII Code und der verschiedenen "Codierungen" von Unicode sind. Und es gibt einige davon, von denen UTF-8, TF-16 und TF-32 sind die aktuellen und einige weitere sind veraltet.

Bitte, UTF-8 (sowie alle anderen Kodierungen ) existieren und haben nur Bedeutung in der Eingabe oder in der Ausgabe. Intern werden seit Perl 5.8.1 alle Zeichenfolgen als Unicode- "Code-Punkte" gespeichert. Richtig, Sie müssen einige Funktionen aktivieren, die zuvor bewundernswert behandelt wurden.

28
MeirG

Es gibt eine wirklich schreckliche Menge an altem Code in freier Wildbahn, viele davon in Form von üblichen CPAN-Modulen. Ich habe festgestellt, dass ich bei der Aktivierung von Unicode ziemlich vorsichtig sein muss, wenn ich externe Module verwende, die möglicherweise davon betroffen sind, und weiterhin versuche, einige Unicode-bezogene Fehler in mehreren von mir regelmäßig verwendeten Perl-Skripten zu identifizieren und zu beheben (insbesondere: iTiVo schlägt bei allen nicht 7-Bit-Versionen fehl ASCII aufgrund von Transcodierungsproblemen).

10
geekosaur

Sie sollten die Unicode-Funktion für Zeichenfolgen aktivieren. Dies ist die Standardeinstellung, wenn Sie Version 5.14 verwenden.

Sie sollten eigentlich keine Unicode-Bezeichner verwenden. für fremden Code über utf8, da sie in Perl5 unsicher sind, hat nur cperl das richtig gemacht. Siehe z. http://Perl11.org/blog/unicode-identifiers.html

In Bezug auf utf8 für Ihre Dateihandles/Streams: Sie müssen die Verschlüsselung Ihrer externen Daten selbst bestimmen. Eine Bibliothek kann das nicht wissen, und da nicht einmal libc utf8 unterstützt, sind richtige utf8-Daten selten. Es gibt mehr wtf8, die Windows-Aberration von utf8.

Übrigens: Moose ist nicht wirklich "Modern Perl", sie haben nur den Namen gekapert. Moose ist perfekt Larry Wall-artiges postmodernes Perl, gemischt mit Bjarne Stroustrup-artigem Perl, mit einer eklektischen Abweichung der richtigen Perl6-Syntax, z. Verwenden von Zeichenfolgen für Variablennamen, Syntax für schreckliche Felder und eine sehr unausgereifte naive Implementierung, die 10x langsamer ist als eine ordnungsgemäße Implementierung. cperl und Perl6 sind die wahren modernen Perls, bei denen form follows function und die Implementierung reduziert und optimiert wird.

1
rurban