Lokalisierung in Perl mit gettext und Locale :: TextDomain mit Fallback, wenn Locale :: TextDomain nicht verfügbar ist

8

Die " Über den Zustand von i18n in Perl "blog Post vom 26. April 2009 empfiehlt, das Modul Locale :: TextDomain aus der libintl-perl-Distribution für l10n / i18n in Perl zu verwenden. Außerdem muss ich sowieso gettext verwenden und die gettext-Unterstützung in Locale :: Messages / Locale :: TextDomain ist natürlicher als in gettext emulation in Locale: : Maketext .

Der Unterabschnitt " 15.5.18 Perl " im Kapitel "15 Andere Programmiersprachen " in GNU Gettext-Handbuch sagt:

  

Portabilität

Das Paket libintl-perl ist plattformunabhängig, aber nicht Teil des Perl-Kerns. Der Programmierer ist dafür verantwortlich, eine Dummy-Implementierung der erforderlichen Funktionen bereitzustellen, wenn das Paket nicht auf dem Zielsystem installiert ist.

Allerdings keines der beiden Beispiele in examples/hello-perl in Gettext-Quellen (eine mit Locale :: Messages auf unterer Ebene, eine mit Locale :: TextDomain auf höherer Ebene) enthält detecting , wenn das Paket auf dem Zielsystem installiert ist und dummy bereitstellt Implementierung falls nicht.

Was das Problem komplizierter macht (in Bezug auf das Erkennen, ob das Paket installiert ist oder nicht), ist das folgende Fragment der Manpage Locale :: TextDomain:

  

SYNOPSIS

%Vor%      

VERWENDUNG

     

Beachten Sie unbedingt, dass Sie Locale :: TextDomain (3) wie im Abschnitt "SYNOPSIS" angegeben verwenden, dh Sie müssen verwenden , nicht require es. Das Modul verhält sich im Vergleich zu anderen Modulen sehr unterschiedlich.

Könnten Sie mir bitte sagen, wie man feststellen sollte, ob libintl-perl auf dem Zielsystem vorhanden ist und wie man eine Dummy-Fallthrough-Implementierung bereitstellen kann, wenn sie nicht installiert ist? Oder geben Sie Beispiele für Programme / Module, die dies tun?

    
Jakub Narębski 03.06.2010, 11:51
quelle

4 Antworten

7

Das gettext-Handbuch ist falsch, um darauf hinzuweisen, dass es für Sie nicht in Ordnung ist, eine CPAN-Voraussetzung zu fordern . Jeder tut das in der Perl-Welt, und dank der CPAN-Infrastruktur und Toolchain funktioniert es gut. Im schlimmsten Fall können Sie die Abhängigkeiten bündeln, die Sie brauchen.

Die direkte Antwort auf Ihre Frage lautet:

%Vor%

Erklärung: use ist nur require zur Kompilierzeit, gefolgt von import und es Es ist akzeptabel, es zu teilen, um dies zur Laufzeit zu erzwingen.

    
daxim 03.06.2010, 16:24
quelle
4

Sie müssen Locale :: TextDomain mit "use" statt "require" einschließen, da es genau für diesen Fall gedacht ist, wenn Sie unauffälliges i18n für Perl wollen, wenn Sie lediglich Ihren Perl-Code internationalisieren müssen:

%Vor%

mit diesem:

%Vor%

In vorverarbeiteten Sprachen wie C ist das einfacher zu erreichen. Über alle internationalisierten C-Bibliotheken enthält #define wie folgt:

%Vor%

Das bedeutet, dass _("Hello world!\n") auf einen Funktionsaufruf erweitert wird, der die Textdomäne Ihres Pakets enthält. Perl-Quellen können nicht portabel vorverarbeitet werden, daher missbraucht Locale::TextDomain den Importmechanismus des Verwendungspragmas für diesen Zweck, so dass er eine .pm-Datei einer bestimmten .mo-Datei zuordnen kann. Die Textdomäne ist der Dateiname der .mo-Dateien, die Ihr Paket installiert.

Wenn Sie diesen Ansatz nicht mögen, verwenden Sie ihn nicht. Sie können auch darauf verzichten:

%Vor%

Allerdings ist Locale::TextDomain populär, weil es das gleiche auf eine weniger aufdringliche Weise tut.

Über die Abhängigkeit von einer Bibliothek, die für Perl kein Kern ist:

Ob ein Perl-Modul zum Perl-Kern gehört oder nicht, hängt von der Perl-Version ab. Und jeder Benutzer kann eine andere Version eines Perl-Kernmoduls installieren als diejenige, die mit Perl ausgeliefert wird. Daher überprüft eine stabile Paketkonfiguration immer die erforderliche Version einer Perl-Bibliothek, so wie sie nach der erforderlichen Version einer anderen Bibliothek sucht. Angenommen, die Prüfung auf Perl ist identisch mit. Überprüfen auf das Vorhandensein einer bestimmten Version eines bestimmten Perl-Moduls ist ein Rezept für Probleme.

BTW, Try::Tiny ist ebenfalls nicht Teil des Perl-Kerns. Vielleicht nicht die beste Wahl, um das Vorhandensein anderer Perl-Module zu überprüfen. Wenn Sie nach libintl-perl testen möchten, führen Sie einfach perl -MLocale::TextDomain -e exit in Ihrem configure-Skript aus und überprüfen Sie den Exit-Status.

    
user2009165 24.01.2013 23:00
quelle
2

Basierend auf der Antwort von daxim, ist hier eine mögliche Implementierung. Es erkennt, ob Locale :: TextDomain verfügbar ist, und bietet einfache No-Op-Fallbacks für __ und __x-Funktionen. Ich würde mich über Verbesserungen und Vorschläge für diesen Code freuen.

%Vor%

Ich denke, der gesamte Code muss innerhalb von BEGIN leben, sonst verursachen die Aufrufe von __ und __x in Ihrem Code Fehler. Außerdem werden die Fallback-Funktionen mit eval () erstellt, um "Prototyp mismatch:" Warnungen zu vermeiden. Ich wäre an einer eleganteren Lösung interessiert. für den letzten Punkt.

    
oliver 24.04.2013 21:21
quelle
1

Erstellen Sie ein Verzeichnis "Fallback / Locale" und erstellen Sie dort ein Modul TextDomain.pm mit Stub-Implementierungen für alle Funktionen, die Sie benötigen:

%Vor%

Fügen Sie nun einen BEGIN-Block in den Einstiegspunkt Ihrer Anwendung ein (normalerweise ein .pl-Skript, kein .pm-Modul):

%Vor%

Jetzt wird Perl immer Locale / TextDomain.pm in @INC finden, im Zweifelsfall die Stub-Implementierung im Fallback-Verzeichnis.

    
Guido Flohr 09.12.2016 12:25
quelle