Website hosting service by Active-Venture.com
  

 Back to Index

USING LOCALES

The use locale pragma

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".

The setlocale function

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).

Finding locales

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.

LOCALE PROBLEMS

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.

Temporarily fixing locale problems

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.

Permanently fixing locale problems

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.

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.

Fixing system locale configuration

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 localeconv function

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";  

I18N::Langinfo

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:

 
    Sun? [yes/no]   

See I18N::Langinfo for more information.

 

  

 

Domain name registration & domain search - 
Register cheap domain name from $7.95 and enjoy free domain services 
 

Cheap domain name search service -
Domain name services at just
$8.95/year only
 


Buy domain name registration and cheap domain transfer at low, affordable price.

2002-2004 Active-Venture.com Web Site Hosting Service

 

[ Artificial Intelligence: the art of making computers that behave like the ones in movies.   ]

 

 
 
 

Disclaimer: This documentation is provided only for the benefits of our web hosting customers.
For authoritative source of the documentation, please refer to http://www.perldoc.com