Locale handling#
A locale is the set of cultural conventions a program follows when it sorts text, changes case, formats numbers and money, names the days of the week, or writes an error message. The same array of words sorts one way under a Swedish locale and another under a German one; the number twelve-and-a-half prints as 12.5 in one country and 12,5 in another. Locale handling is how Perl lets a single program adapt to those conventions at runtime instead of hard-coding one country’s rules.
By default PetaPerl ignores locale entirely: every built-in behaves the same regardless of the user’s environment, using the C/POSIX conventions (ASCII collation, . as the decimal point, English month names). You opt in to locale-awareness, one lexical scope at a time, with the use locale pragma. This page covers what that pragma turns on, which operations it affects, how to set and inspect the active locale, and where locale and Unicode interact.
What a locale is#
The system C library divides cultural conventions into independent categories, each named LC_ followed by the area it governs. Sorting (LC_COLLATE) is separate from case rules (LC_CTYPE), which is separate from number formatting (LC_NUMERIC), and so on. A locale is a named bundle of settings - de_DE.UTF-8, sv_SE.UTF-8, C - and switching to it can change all categories at once or just the ones you select. The categories PetaPerl honours are listed in the category table below.
The use locale pragma#
Locale-sensitive behaviour is off by default and lexically scoped. use locale enables it from that point to the end of the enclosing block (or file); no locale turns it back off for the remainder of its own scope. Nothing outside the lexical scope is affected - a module that does not say use locale keeps the default C-locale behaviour even when called from code that did.
use locale; # locale-aware from here down
my @sorted = sort @words; # collates per LC_COLLATE
{
no locale; # back to codepoint order in this block
my @plain = sort @words;
}
Without the pragma, sort, lc, uc, printf and the rest use fixed C-locale rules no matter what the environment says. This is a deliberate safety default: a program produces the same output on every machine until it explicitly asks to follow the local conventions.
The pragma sets a per-statement hint, exactly as upstream Perl does, so a single file can mix locale-aware and locale-blind regions freely. The setting travels with the lexical scope, not with the call stack.
Locale categories#
Each category controls a distinct group of operations. use locale activates all of them at once; you choose which locale is active per category through setlocale. The “affected operations” column links to the reference pages where the behaviour is documented in full - that is where the locale-specific rules for each built-in live.
Category | Governs | Affected operations |
|---|---|---|
| String sort order and comparison |
|
| Character classification and case mapping | |
| Decimal point and digit grouping | |
| Currency formatting conventions |
|
| Day and month names, date layout | |
| Language of system error strings |
LC_ALL is not a category of its own but a shorthand that sets every category at once.
Note one asymmetry that trips people up: LC_NUMERIC changes how numbers are formatted for output, but Perl’s own source code and its numeric parsing always use . as the decimal separator. A script that reads 12,5 from a German-locale file still needs to translate the comma itself before treating it as a number - the locale does not make "12,5" + 0 yield 12.5. See numbers and strings.
Setting the locale#
use locale says follow the locale; it does not say which one. That choice comes from the environment by default, and you can query or override it through the POSIX module.
setlocale selects the active locale for a category. The idiomatic call honours the user’s environment (LANG, LC_*):
use POSIX qw(setlocale LC_ALL LC_COLLATE);
setlocale(LC_ALL, ""); # adopt the environment's locale
my $cur = setlocale(LC_COLLATE); # query the active collation
setlocale(LC_COLLATE, "sv_SE.UTF-8"); # force one explicitly
localeconv returns a hash describing the active LC_NUMERIC and LC_MONETARY conventions - the decimal point, thousands separator, currency symbol, and the rest - so a program can format values itself when no built-in does it directly.
I18N::Langinfo exposes langinfo, which reads individual items out of the current locale: the localized name of a weekday or month (DAY_1, MON_1), the date format string, the radix character, the currency symbol. It is the narrow, item-at-a-time companion to localeconv.
Locale and Unicode#
Locale handling and Unicode are two different answers to “what is a character”, and they interact in ways worth understanding before you combine them. The full treatment - how use utf8, UTF-8 I/O layers, and locale LC_CTYPE rules compose, and the traps that arise when they disagree - lives in the Unicode tutorial. Start with Unicode strings and encodings and the pitfalls chapter; the regex-and-properties chapter covers how \w and the character classes behave under each model.
Locale leaks and safety#
A locale is process-global state in the C library underneath, so a setlocale call made anywhere changes the locale everywhere in the process - across module boundaries, not just the scope that called it. Two consequences follow:
use localeis safe to scope;setlocaleis not. The pragma is lexical and leaks nothing. Asetlocalecall is a global side effect - if a library setsLC_NUMERICto a comma-decimal locale and forgets to restore it, every laterprintfin the program is affected. Save and restore around a temporary change:my $saved = setlocale(LC_NUMERIC); setlocale(LC_NUMERIC, "de_DE.UTF-8"); # ... locale-sensitive work ... setlocale(LC_NUMERIC, $saved);
Untrusted locale names are untrusted input. Passing an environment-supplied string straight to
setlocalelets the environment steer your program’s formatting. In a security-sensitive context, validate the name or pin the locale explicitly rather than callingsetlocale(LC_ALL, "").
Parallel execution and locale#
PetaPerl auto-parallelizes some numeric loops across worker threads. This never affects locale-sensitive code, by construction. Operations whose results depend on the current locale - sort with the default collation, LC_COLLATE string comparison, lc/uc/fc case folding, and LC_NUMERIC number formatting - are never JIT-compiled or auto-parallelized; they always execute sequentially in the interpreter against the single process-wide locale. Auto-parallelization only ever runs numeric loop bodies, so no locale-sensitive computation is dispatched across worker threads. You do not need to guard locale state when writing parallelizable code: the parallel path simply never touches it.
Environment variables#
When a program calls setlocale(LC_ALL, ""), the C library reads the locale from the environment in a fixed order of precedence: LC_ALL overrides every individual LC_* variable, each LC_* variable sets its own category, and LANG supplies the default for any category not otherwise named. These variables live in %ENV like any other environment value, so a program can inspect or adjust them before the setlocale call that consumes them.
Variable | Effect |
|---|---|
| Overrides all categories |
| Sets one named category |
| Default for any category not set above |
Differences from upstream#
Linux only, UTF-8 native. PetaPerl runs only on Linux against the system C library’s locales. The platform-specific locale machinery upstream Perl carries for VMS, Windows, and Android - the
Win32::locale shims, the VMS category quirks, the “locales are not available on this platform” fallbacks - has no counterpart here and is simply absent. There is one locale model: the POSIX one yourglibcprovides.LC_NUMERICand source parsing. As upstream, the decimal separator used when Perl parses numeric literals and string-to-number conversions is always., regardless of locale; only formatting output respectsLC_NUMERIC. PetaPerl makes no exception to this.Auto-parallelization never touches locale-sensitive code. PetaPerl auto-parallelizes some numeric loops across worker threads, a capability upstream Perl does not have. Because locale-dependent operations (collation, case folding, number formatting) are never JIT-compiled or parallelized, they always run sequentially against the single process-wide locale - so the feature introduces no locale-safety concern of its own. See Parallel execution and locale above.
See also#
perlfunc- the built-ins whose behaviour locale changes:sort,lc,uc,lcfirst,ucfirst,sprintf,printf.perlop- the string comparison operators (lt,cmp, …) that collate underLC_COLLATE.perlvar-%ENVholds theLANG/LC_*variables;$!carries locale-translated error text.POSIX-setlocaleandlocaleconv, the interface for choosing and inspecting the active locale.I18N::Langinfo-langinfo, for reading one localized item (month name, radix character) at a time.-
how the Unicode character model relates to locale
LC_CTYPE.