Blog ·
Sechzehntausend Schlüssel, neun Sprachen
Ein Steuerungspanel zu übersetzen ist kein Textproblem. Die Fehler, auf die es ankommt, sind still: ein verlorenes Argument, ein eingeebneter Plural.
Von Provibr
Unser englischer Nachrichtenkatalog enthält derzeit etwas über sechzehntausend Zeichenketten. Es gibt neun davon, einen je Sprache, und sie müssen genau dieselben Schlüssel haben. Das sind gut über hundertvierzigtausend Textstücke, die einander alle treu bleiben müssen, während ein Dutzend Menschen das Produkt darunter verändert.
Das Interessante an diesem Problem ist nicht die Menge. Es ist, dass sich fast keiner der Fehlschläge zu erkennen gibt. Eine Übersetzung mit einem Tippfehler wird binnen einer Woche von einem Kunden gemeldet. Eine Übersetzung, die still ein Argument verloren hat, stellt für immer einen Satz mit einem Loch dar, und niemand meldet einen Satz, der sich gut liest.
Das ist die Menge an Prüfungen, bei der wir gelandet sind, samt der Begründung für jede. Sie sind an kein Rahmenwerk gebunden; die Fehlerarten sind eine Eigenschaft davon, mehr als eine Sprache zu haben.
Die Fehlerklasse, auf die es ankommt
Beginnen wir mit der, die uns die Sache ernst nehmen ließ.
Eine englische Zeichenkette lautet Welcome back, {name}. Jemand übersetzt sie, und die Übersetzung lautet Welcome back. Sie ist grammatisch, sie ist ein vernünftiger Satz, und sie stellt sich in jedem existierenden Vorlagensystem ohne Fehler dar. Der Parameter erscheint schlicht nicht. Es gibt keine Ausnahme, keine Protokollzeile, keine Warnung über einen fehlenden Schlüssel.
Dieser Fehler ist für jeden Test unsichtbar, der prüft, ob Schlüssel existieren, und das ist der Test, den fast jeder zuerst schreibt. Das Einzige, was ihn findet, ist ein Vergleich: die Menge der Platzhalternamen aus der Referenzzeichenkette ziehen, dieselbe aus der Übersetzung ziehen und Übereinstimmung verlangen.
Hat man diesen Vergleich einmal gebaut, erweisen sich drei Verfeinerungen als nötig, und jede stammt von einer echten Zeichenkette, die durchgerutscht ist.
Vergleichen Sie Argumenttypen, nicht nur Namen. Ein nacktes {count} formatiert nicht. Es gibt die rohe Zahl aus, ohne Tausendertrennzeichen, in jeder Sprache. Schreiben Sie {count, number}, und es formatiert. Ist der Typ im Englischen vorhanden und in der Übersetzung nicht, stimmt der Name, stimmt die Zweigstruktur, und eine Sprache stellt still eine rohe ganze Zahl dar, wo die anderen eine formatierte darstellen. Dasselbe gilt für Datumsangaben: Ein Datumsargument, das seinen Typ verloren hat, stellt der lesenden Person einen ISO-Zeitstempel hin.
Vergleichen Sie keine Argumentstile. Währungsstil gegen einfachen Zahlenstil ist eine Darstellungsentscheidung, die sich je Sprache berechtigterweise unterscheidet, und eine Prüfung, die das anmahnt, bringt den Leuten bei, die Prüfung zu ignorieren. Der Typ ist strukturell, der Stil ist Geschmack, und nur eines davon gehört in einen Test.
Vergleichen Sie Zweignamen, nicht Zweigtexte. Ein Plural, den die übersetzende Person eingeebnet hat, behält sein Argument, ein Platzhaltervergleich lässt ihn also bereitwillig durch, während auf dem Bildschirm am Ende eine nackte Zahl ohne folgendes Substantiv steht. Genau das hatten wir in unserem niederländischen Katalog, und so wurde es gefunden.
Pluralformen sind kein gelöstes Problem zum Abschreiben
Der Reflex ist, zu verlangen, dass eine Übersetzung dieselben Pluralzweige hat wie das Englische. Das Englische hat zwei: one und other. Diese Forderung ist richtig für die Sprachen, die ebenfalls zwei haben, und sie ist genau falsch für die, die es nicht tun, denn sie akzeptiert bereitwillig einen Katalog, dem Kategorien fehlen, die seine eigene Sprache braucht.
Ein paar Messungen, alle aus den Standardregeln, die jede moderne Laufzeitumgebung mitbringt:
| Sprache | Was Menschen überrascht |
|---|---|
| Französisch | Die Null nimmt den Singularzweig. „0 machine“, nicht „0 machines“. |
| Ukrainisch | Vier Kategorien. Die Null fällt in many, zusammen mit 5 bis 20; 21 ist one und 22 ist few. |
| Rumänisch | 2 bis 19 ist few, 20 ist other, und 101 ist wieder few. |
| Arabisch | Sechs Kategorien, geteilt bei 0, 1, 2, 3 bis 10 und 11 bis 99. |
Die Zeile zum Rumänischen hat eine Folge, die sich als schiere Menge zeigt. Das Rumänische setzt oberhalb von neunzehn eine Präposition vor das Substantiv, eine Wendung, die im Englischen überhaupt keinen Plural braucht, braucht im Rumänischen also einen. Zählt man die Nachrichten in unseren Katalogen, die einen Plural enthalten: Das Englische hat 319, das Rumänische 498. 179 Nachrichten brauchen im Rumänischen eine Pluralkonstruktion, die das Englische überhaupt nicht braucht. Das Ukrainische fügt 13 eigene hinzu, das Französische 4.
Hier ist eine davon, und es ist vollkommen gewöhnliches Englisch:
en: Start {days}-day trial
uk: Почати пробний період на {days, plural, one {# день} few {# дні} many {# днів} other {# дня}}Nichts am englischen Satz deutet darauf hin, dass er ein Pluralproblem ist. Eine Prüfung, die ihre Erwartungen aus dem Englischen ableitet, kann das unmöglich sehen.
Die zweite Prüfung läuft deshalb je Sprache gegen ihren eigenen Katalog: Ist für jeden Plural darin jede Kategorie behandelt, die diese Sprache tatsächlich erzeugen kann, sei es über den Namen oder über einen Zweig mit genauem Wert?
Diese Prüfung braucht eine bewusste Grenze, sonst wird sie nutzlos. Das Französische und das Spanische haben eine Kategorie many, die nur für genaue Vielfache einer Million gilt. Sie überall zu verlangen würde Hunderte Zweige hinzufügen, die kein Mensch je sehen wird, in einem Produkt, das Server, Adressen, Teammitglieder und Tage zählt. Die Prüfung ist deshalb stichprobengesteuert: Sie fragt, welche Kategorien für die Anzahlen erreichbar sind, die ein Schlüssel realistisch sieht, und es gibt eine kleine ausdrückliche Liste von Schlüsseln, die höher zählen, damit die Maschinerie an dem Tag bereitsteht, an dem etwas es tut.
Diese Liste ist derzeit leer, und das ist eine Messung und kein Versäumnis. Die beiden Kandidaten, die groß werden könnten, zählen Bytes, und die französische Regel will ein genaues Vielfaches einer Million; eine Datei von exakt 1.000.000 Bytes ist ein Zufall und kein Fall.
Die Prüfung, die still gar nichts tat
Jetzt die unangenehme, denn es ist der Fehlschlag, um den dieser ganze Artikel geht, angewandt auf das Werkzeug selbst.
Wir haben eine Prüfung, dass jeder Übersetzungsaufruf im Code auf einen Schlüssel verweist, den es gibt. Sie zerlegt den Quelltext, verfolgt, welches Übersetzerobjekt zu welchem Namensraum gehört, und schlägt jeden Schlüssel nach. Sie meldete, dass sie mehrere tausend Schlüssel abdeckte. Sie war grün.
Sie übersprang außerdem jeden Aufruf, der aus einem Destrukturierungsmuster stammte, denn der Code, der einen Übersetzer an einen Namensraum band, behandelte nur einen einfachen Bezeichner und ignorierte still alles andere. Keine Bindung, also kein zu prüfender Schlüssel, also kein Fehlschlag. Das Muster, das sie übersprang, war zufällig das, welches in fast unserer ganzen Anwendung benutzt wird.
Wir fanden es, weil jemand einen Schlüsselnamen riet, ihn schrieb, und der Test grün blieb.
Daraus kamen zwei Regeln, und wir wenden beide jetzt auf jede statische Analyse an, die wir schreiben.
Eine Analyse, die auf eine Form trifft, die sie nicht versteht, muss laut scheitern und nicht still überspringen. Unbekannt ist ein Befund und kein Nichtstun. Der ganze Wert des Werkzeugs liegt darin, dass es sich alles angesehen hat.
Beweisen Sie die Prüfung rot, bevor Sie ihr grün vertrauen. Machen Sie absichtlich etwas kaputt und sehen Sie zu, wie der Test scheitert. Eine Prüfung, die nie gescheitert ist, wurde nicht getestet; sie wurde nur ausgeführt.
Ein naher Verwandter dieser Lektion: Ein Markenname wurde in unseren Katalogen auf vier verschiedene Weisen geschrieben, und die eine Stelle im ganzen Quelltext, die die richtige Schreibweise kannte, kannte sie als Ausnahme in einer Erlaubnisliste. Der einzige Bestandteil, der die richtige Antwort hatte, war so eingerichtet, dass er von ihr wegsah. Eine Ausnahme ist keine Prüfung, und die Reparatur besteht meist darin, die Sache umzukehren: die Regel aussprechen und die Ausnahmen als Daten daran hängen lassen.
Das eigene Nachrichtenformat zu parsen ist schwerer als gedacht
Platzhalter mit einem regulären Ausdruck zu ziehen funktioniert, bis es das nicht mehr tut, und die Art, wie es scheitert, ist lehrreich, denn es scheitert an Ihren besten Zeichenketten.
Ein Auswahlzweig, dessen Text ein einziges Wort ist, sieht für einen Mustervergleicher genau aus wie ein Argument. Unser alter Scanner schlug bei den sorgfältigsten Nachrichten im Katalog falschen Alarm und übersah gleichzeitig echte Argumente innerhalb von Zweigen, denn ein regulärer Ausdruck kann keine geschweiften Klammern zählen. Er lag in beide Richtungen gleichzeitig falsch.
Der Ersatz läuft die Klammern richtig ab und steigt in Zweigkörper hinab. Er ist dreißig Zeilen lang statt einer, und er ist der Unterschied zwischen einer Prüfung, der Menschen vertrauen, und einer, um die herum Menschen sich Ausnahmen schreiben.
Typografie ist eine Prüfung je Sprache, keine gemeinsame
Die letzte Kategorie lässt sich überhaupt nicht durch Vergleich prüfen, denn sie ist genau das, was sich zwischen den Sprachen unterscheidet. Das Französische will ein geschütztes Leerzeichen vor Doppelpunkt, Semikolon, Ausrufezeichen und Fragezeichen. Das Ukrainische will ein bestimmtes Apostrophzeichen, das aussieht wie die zwei anderen Apostrophe, die Sie vermutlich auf Ihrer Tastatur haben. Das Spanische eröffnet eine Frage mit einem umgekehrten Zeichen, an der Stelle, an der die Frage beginnt, und nicht am Satzanfang. Das Rumänische benutzt eigene Anführungszeichen und Diakritika mit Komma darunter.
Nichts davon ist über Sprachen hinweg vergleichbar, also bekommt jede Sprache, die Regeln hat, ihre eigene Prüfung. Das klingt nach Doppelung und ist es nicht: Die Alternative ist eine einzige allgemeine Prüfung, die nur die Schnittmenge von neun Regelwerken behaupten kann, und die ist für praktische Zwecke leer.
Eine Warnung aus der Arbeit damit in einem großen Verzeichnisbaum: Ein geschütztes Leerzeichen ist unsichtbar, und mehrere Werkzeuge wandeln es unterwegs hilfsbereit in ein gewöhnliches Leerzeichen um. Wir setzen sie genau deshalb mit einem Skript ein und prüfen danach, dass sie noch da sind.
Was wir zuerst bauen würden, der Reihe nach
Wenn Sie bei einer einzigen Sprache anfangen und mit weiteren rechnen, ist das die Reihenfolge, die uns am meisten erspart hätte.
- Dieselben Schlüssel in jedem Katalog, geprüft in der CI. Billig, und es ist das Fundament, auf dem der Rest steht.
- Vergleich von Platzhaltern und Argumenttypen gegen die Referenzsprache. Das ist der, der die stillen Fehler fängt.
- Vergleich der Zweignamen für Plural und Auswahl, damit ein eingeebneter Plural ein Fehlschlag ist.
- Pluralabdeckung je Sprache, gesteuert von den eigenen Regeln der Sprache, bevor die erste Sprache eintrifft, die mehr Kategorien braucht als Ihre Referenz.
- Typografie je Sprache, eine kleine Prüfung je Sprache, die Konventionen hat.
- Eine statische Prüfung, dass jeder im Code angesprochene Schlüssel existiert und, wichtiger, dass sie ehrlich über die Aufrufe ist, die sie nicht verstehen konnte.
Das Thema, das sich durch alle sechs zieht, ist, dass Übersetzungsfehler nicht werfen. Sie stellen dar. Jede Prüfung hier existiert, weil sich etwas vollkommen richtig dargestellt hat, in einer Sprache, die niemand im Raum liest, und etwas leicht anderes gesagt hat als das, was wir meinten.