3

I'm debugging a perl script which looks like this (simplified):

#!/usr/bin/perl    
use strict;
use warnings;

use Evil::Module;

printf "%.3f\n", 0.1;

This script outputs 0,100 (note , instead of .). If I comment out the use Evil::Module statement, the output will be 0.100.

I believe that this is related to locale setting in the module. But locale is a lexical pragma (according to the manpage), and it's not used within the script. What's happening here?

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378

2 Answers2

5

The use locale pragma is lexical, but if the Evil::Module module uses POSIX::setlocale, then the locale change is global.

See perldoc perllocale for more information.

mob
  • 117,087
  • 18
  • 149
  • 283
  • @Hynek - you either must REALLY hate JavaScript and not do any web development, or it was a poor attempt at humour, or you need to learn to distinguish between a possibly bad feature of a language - as well as code implemented by specific developers in that language - and a language itself. – DVK Jul 09 '10 at 19:43
  • @DVK: You found it. I don't do web development in JavaScript. Anyway I 'm working on 200k SLOC perl project and I know very well what I'm talking about. I have been in love with perl for seven years and for several tens thousands perl SLOC but I get sense. It is $_, $@, $!, $?, ... what bite you together with DESTROY or signal handler or anything else. It is bad feature of a language itself. – Hynek -Pichi- Vychodil Jul 09 '10 at 23:26
  • 1
    @Hynek: Yes, but no matter how much you dislike Perl, the POSIX locale stuff is *really* evil. It's quite stunningly misconceived, and it causes problems across many thousands of applications. – Donal Fellows Jul 09 '10 at 23:51
  • @Donal: Yes it is yet another global variable. – Hynek -Pichi- Vychodil Jul 11 '10 at 07:44
  • @Hynek: If you've ever wanted to write a multi-threaded application which deals with multiple locales, that's when you get to see just how horrible the POSIX locale system is. The only way to tame it is to force the use of the C locale for everything and use a different, explicit locale system. (POSIX locales are evil in every language. They manage to be evil even in languages which don't use them, if the code happens to access a library which does. I've seen that happen in vendor-supplied print dialogs…) – Donal Fellows Jul 11 '10 at 09:33
1

Here's an excerpt from perldoc perllocale which makes the issue clear:

write() and LC_NUMERIC

Formats are the only part of Perl that unconditionally use information from a program's locale; if a program's environment specifies an LC_NUMERIC locale, it is always used to specify the decimal point character in formatted output. Formatted output cannot be controlled by use locale because the pragma is tied to the block structure of the program, and, for historical reasons, formats exist outside that block structure.

It seems that print() and printf() have the same behaviour.

Community
  • 1
  • 1
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378