USING LOCALES
By default, Perl ignores the current locale. The use locale pragma tells
Perl to use the current locale for some operations:
-
The comparison operators (lt, le, cmp, ge,
and gt) and the POSIX string collation functions strcoll() and strxfrm() use LC_COLLATE.
sort() is also affected if used without an explicit comparison function, because it uses cmp
by default.
Note: eq and ne are unaffected by locale: they always
perform a char-by-char comparison of their scalar operands. What's more, if cmp
finds that its operands are equal according to the collation sequence specified by the
current locale, it goes on to perform a char-by-char comparison, and only returns 0
(equal) if the operands are char-for-char identical. If you really want to know whether
two strings--which eq and cmp may consider different--are equal
as far as collation in the locale is concerned, see the discussion in Category LC_COLLATE: Collation.
- Regular expressions and case-modification functions (uc(), lc(), ucfirst(), and
lcfirst()) use
LC_CTYPE
- The formatting functions (printf(), sprintf() and write()) use
LC_NUMERIC
- The POSIX date formatting function (strftime()) uses
LC_TIME.
LC_COLLATE, LC_CTYPE, and so on, are discussed further in LOCALE CATEGORIES.
The default behavior is restored with the no locale pragma, or upon
reaching the end of block enclosing use locale.
The string result of any operation that uses locale information is tainted, as it is
possible for a locale to be untrustworthy. See "SECURITY".
You can switch locales as often as you wish at run time with the POSIX::setlocale()
function:
# This functionality not usable prior to Perl 5.004
require 5.004;
# Import locale-handling tool set from POSIX module.
# This example uses: setlocale -- the function call
# LC_CTYPE -- explained below
use POSIX qw(locale_h);
# query and save the old locale
$old_locale = setlocale(LC_CTYPE);
setlocale(LC_CTYPE, "fr_CA.ISO8859-1");
# LC_CTYPE now in locale "French, Canada, codeset ISO 8859-1"
setlocale(LC_CTYPE, "");
# LC_CTYPE now reset to default defined by LC_ALL/LC_CTYPE/LANG
# environment variables. See below for documentation.
# restore the old locale
setlocale(LC_CTYPE, $old_locale);
|
|
The first argument of setlocale() gives the category, the second the locale.
The category tells in what aspect of data processing you want to apply locale-specific rules.
Category names are discussed in LOCALE CATEGORIES and "ENVIRONMENT". The locale is the name of a collection of
customization information corresponding to a particular combination of language, country or
territory, and codeset. Read on for hints on the naming of locales: not all systems name
locales as in the example.
If no second argument is provided and the category is something else than LC_ALL, the
function returns a string naming the current locale for the category. You can use this value
as the second argument in a subsequent call to setlocale().
If no second argument is provided and the category is LC_ALL, the result is
implementation-dependent. It may be a string of concatenated locales names (separator also
implementation-dependent) or a single locale name. Please consult your setlocale(3) for details.
If a second argument is given and it corresponds to a valid locale, the locale for the
category is set to that value, and the function returns the now-current locale value. You can
then use this in yet another call to setlocale(). (In some implementations, the return value
may sometimes differ from the value you gave as the second argument--think of it as an alias
for the value you gave.)
As the example shows, if the second argument is an empty string, the category's locale is
returned to the default specified by the corresponding environment variables. Generally, this
results in a return to the default that was in force when Perl started up: changes to the
environment made by the application after startup may or may not be noticed, depending on your
system's C library.
If the second argument does not correspond to a valid locale, the locale for the category
is not changed, and the function returns undef.
For further information about the categories, consult setlocale(3).
For locales available in your system, consult also setlocale(3) to see whether it
leads to the list of available locales (search for the SEE ALSO section). If that
fails, try the following command lines:
locale -a
nlsinfo
ls /usr/lib/nls/loc
ls /usr/lib/locale
ls /usr/lib/nls
ls /usr/share/locale
|
|
and see whether they list something resembling these
en_US.ISO8859-1 de_DE.ISO8859-1 ru_RU.ISO8859-5
en_US.iso88591 de_DE.iso88591 ru_RU.iso88595
en_US de_DE ru_RU
en de ru
english german russian
english.iso88591 german.iso88591 russian.iso88595
english.roman8 russian.koi8r
|
|
Sadly, even though the calling interface for setlocale() has been standardized, names of
locales and the directories where the configuration resides have not been. The basic form of
the name is language_territory.codeset, but the latter parts after language
are not always present. The language and country are usually from the standards ISO
3166 and ISO 639, the two-letter abbreviations for the countries and the languages
of the world, respectively. The codeset part often mentions some ISO 8859
character set, the Latin codesets. For example, ISO 8859-1 is the so-called
"Western European codeset" that can be used to encode most Western European
languages adequately. Again, there are several ways to write even the name of that one
standard. Lamentably.
Two special locales are worth particular mention: "C" and "POSIX".
Currently these are effectively the same locale: the difference is mainly that the first one
is defined by the C standard, the second by the POSIX standard. They define the default
locale in which every program starts in the absence of locale information in its
environment. (The default default locale, if you will.) Its language is (American)
English and its character codeset ASCII.
NOTE: Not all systems have the "POSIX" locale (not all systems are POSIX-conformant),
so use "C" when you need explicitly to specify this default locale.
You may encounter the following warning message at Perl startup:
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LC_ALL = "En_US",
LANG = (unset)
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
|
|
This means that your locale settings had LC_ALL set to "En_US" and LANG exists
but has no value. Perl tried to believe you but could not. Instead, Perl gave up and fell back
to the "C" locale, the default locale that is supposed to work no matter what. This
usually means your locale settings were wrong, they mention locales your system has never
heard of, or the locale installation in your system has problems (for example, some system
files are broken or missing). There are quick and temporary fixes to these problems, as well
as more thorough and lasting fixes.
The two quickest fixes are either to render Perl silent about any locale inconsistencies or
to run Perl under the default locale "C".
Perl's moaning about locale problems can be silenced by setting the environment variable
PERL_BADLANG to a zero value, for example "0". This method really just sweeps the
problem under the carpet: you tell Perl to shut up even when Perl sees that something is
wrong. Do not be surprised if later something locale-dependent misbehaves.
Perl can be run under the "C" locale by setting the environment variable LC_ALL
to "C". This method is perhaps a bit more civilized than the PERL_BADLANG approach,
but setting LC_ALL (or other locale variables) may affect other programs as well, not just
Perl. In particular, external programs run from within Perl will see these changes. If you
make the new settings permanent (read on), all programs you run see the changes. See ENVIRONMENT for the full list
of relevant environment variables and USING LOCALES for their
effects in Perl. Effects in other programs are easily deducible. For example, the variable
LC_COLLATE may well affect your sort program (or whatever the program that arranges
`records' alphabetically in your system is called).
You can test out changing these variables temporarily, and if the new settings seem to
help, put those settings into your shell startup files. Consult your local documentation for
the exact details. For in Bourne-like shells (sh, ksh, bash, zsh):
LC_ALL=en_US.ISO8859-1
export LC_ALL
|
|
This assumes that we saw the locale "en_US.ISO8859-1" using the commands
discussed above. We decided to try that instead of the above faulty locale "En_US"--and
in Cshish shells (csh, tcsh)
setenv LC_ALL en_US.ISO8859-1
|
|
or if you have the "env" application you can do in any shell
env LC_ALL=en_US.ISO8859-1 perl ...
|
|
If you do not know what shell you have, consult your local helpdesk or the equivalent.
The slower but superior fixes are when you may be able to yourself fix the misconfiguration
of your own environment variables. The mis(sing)configuration of the whole system's locales
usually requires the help of your friendly system administrator.
First, see earlier in this document about Finding locales.
That tells how to find which locales are really supported--and more importantly, installed--on
your system. In our example error message, environment variables affecting the locale are
listed in the order of decreasing importance (and unset variables do not matter). Therefore,
having LC_ALL set to "En_US" must have been the bad choice, as shown by the error
message. First try fixing locale settings listed first.
Second, if using the listed commands you see something exactly (prefix matches do
not count and case usually counts) like "En_US" without the quotes, then you should
be okay because you are using a locale name that should be installed and available in your
system. In this case, see Permanently
fixing your system's locale configuration.
This is when you see something like:
perl: warning: Please check that your locale settings:
LC_ALL = "En_US",
LANG = (unset)
are supported and installed on your system.
|
|
but then cannot see that "En_US" listed by the above-mentioned commands. You may
see things like "en_US.ISO8859-1", but that isn't the same. In this case, try
running under a locale that you can list and which somehow matches what you tried. The rules
for matching locale names are a bit vague because standardization is weak in this area. See
again the Finding locales about general rules.
Contact a system administrator (preferably your own) and report the exact error message you
get, and ask them to read this same documentation you are now reading. They should be able to
check whether there is something wrong with the locale configuration of the system. The Finding locales section is unfortunately a bit vague about the
exact commands and places because these things are not that standardized.
The POSIX::localeconv() function allows you to get particulars of the locale-dependent
numeric formatting information specified by the current LC_NUMERIC and LC_MONETARY
locales. (If you just want the name of the current locale for a particular category, use
POSIX::setlocale() with a single parameter--see The
setlocale function.)
use POSIX qw(locale_h);
# Get a reference to a hash of locale-dependent info
$locale_values = localeconv();
# Output sorted list of the values
for (sort keys %$locale_values) {
printf "%-20s = %s\n", $_, $locale_values->{$_}
}
|
|
localeconv() takes no arguments, and returns a reference to a hash. The keys of this
hash are variable names for formatting, such as decimal_point and thousands_sep.
The values are the corresponding, er, values. See POSIX/localeconv
for a longer example listing the categories an implementation might be expected to provide;
some provide more and others fewer. You don't need an explicit use locale,
because localeconv() always observes the current locale.
Here's a simple-minded example program that rewrites its command-line parameters as
integers correctly formatted in the current locale:
# See comments in previous example
require 5.004;
use POSIX qw(locale_h);
# Get some of locale's numeric formatting parameters
my ($thousands_sep, $grouping) =
@{localeconv()}{'thousands_sep', 'grouping'};
# Apply defaults if values are missing
$thousands_sep = ',' unless $thousands_sep;
# grouping and mon_grouping are packed lists
# of small integers (characters) telling the
# grouping (thousand_seps and mon_thousand_seps
# being the group dividers) of numbers and
# monetary quantities. The integers' meanings:
# 255 means no more grouping, 0 means repeat
# the previous grouping, 1-254 means use that
# as the current grouping. Grouping goes from
# right to left (low to high digits). In the
# below we cheat slightly by never using anything
# else than the first grouping (whatever that is).
if ($grouping) {
@grouping = unpack("C*", $grouping);
} else {
@grouping = (3);
}
# Format command line params for current locale
for (@ARGV) {
$_ = int; # Chop non-integer part
1 while
s/(\d)(\d{$grouping[0]}($|$thousands_sep))/$1$thousands_sep$2/;
print "$_";
}
print "\n";
|
|
Another interface for querying locale-dependent information is the I18N::Langinfo::langinfo()
function, available at least in UNIX-like systems and VMS.
The following example will import the langinfo() function itself and three constants to be
used as arguments to langinfo(): a constant for the abbreviated first day of the week (the
numbering starts from Sunday = 1) and two more constants for the affirmative and negative
answers for a yes/no question in the current locale.
use I18N::Langinfo qw(langinfo ABDAY_1 YESSTR NOSTR);
my ($abday_1, $yesstr, $nostr) = map { langinfo } qw(ABDAY_1 YESSTR NOSTR);
print "$abday_1? [$yesstr/$nostr] ";
|
|
In other words, in the "C" (or English) locale the above will probably print
something like:
See I18N::Langinfo for more information.
|