Locale::TextDomain fails when $LANG is not initially set
We have a system of translation that uses perl Locale::TextDomain/gettext. We have an issue where the localization works on one system and not the other.
The only discernible difference is that environment variable LANG equals 'en_GB.UTF-8' on the working system and LANG is not defined on the non-working system. The non working system has no /etc/default/locale
exporting LANG on the broken system makes it 开发者_运维百科work and unsetting on the working system breaks it.
The following script demonstrates:
#!/usr/bin/perl
use strict;
use warnings;
use Locale::TextDomain ('appdomain', '/path/to/language/folders');
use POSIX (':locale_h');
setlocale(LC_ALL, '');
$ENV{'LANGUAGE'} = 'it';
print __('Back'), "\n";
Why does there need to be an initial $LANG set if we're specifying the LANGUAGE anyway?
Running 'Ubuntu 10.04.2 LTS' and Locale::TextDomain 1.20
The locale "" (the empty string) denotes the system locale. All known Un*x implementations of setlocale() use then environment variables to set the locale. You are setting the environment variable after the call to setlocale(), and it is therefore ignored.
Locale::TextDomain does not fail here. It is a configuration error.
There are several approaches for fixing such problems. If you know the language that you want to use you can let libintl-perl do the heavy liftings:
use Locale::Util qw(set_locale);
set_locale(LC_MESSAGES, 'pt', 'BR', 'utf-8');
The call to set_locale() will try all known conventions for locale identifiers for setting the language to Portuguese 'pt' for Brazil ('BR'). It will also try to select a UTF-8 locale. See http://search.cpan.org/dist/libintl-perl/lib/Locale/Util.pm#FUNCTIONS for more information! The name set_locale() was intentionally chosen to avoid a name clash with setlocale() from POSIX.pm.
Beginning with libintl-perl 1.22, you can also switch to the "dumb" gettext backend:
use Locale::Messages qw(select_package);
BEGIN { Locale::Messages->select_package('gettext_dumb') }
The "dumb" backend never bothers to call setlocale() to find the current locale settings but only inspects environment variables. Please see http://search.cpan.org/dist/libintl-perl/lib/Locale/gettext_dumb.pm for the pros and cons of this approach. The biggest disadvantage is that C code does not honor this, so that $! for example will not use the configured language.
Alternatively you can switch to the 'gettext_pp' backend just as described for 'gettext_dumb' above. This will force using the pure Perl implementation of the gettext runtime. The main advantage of this is actually that it is easier to debug. But there are also subtle differences to the C implementation.
Just a side note: You should keep in mind that the environment variable LANGUAGE is a GNU extension and may not work in a non-GNU environment.
$LANG
is the system-wide default variable used across most Unixy systems. $LANGUAGE
is for more specific purposes.
Systems these days really ought to have $LANG
set to a sensible default. Get the sysadmin to put it in /etc/profile
or wherever it need to be for system-wide shell defaults.
精彩评论