wwe has asked for the wisdom of the Perl Monks concerning the following question:

Hi dear monks, I came over a strage behaviour with print/say built-ins using setlocale. I tried to localize floating point representation using setlocale. I observed different behavior of print/say statements according to how I use them. If I use a point operator to concatenate some numbers and strings to a single statement
say "bla bla" . 1/2 . " bla bla
prints "bla bla 0.5 bla bla". If I pass a list the localized german represantation with comma is used
say 'bla bla ', 1/2, ' bla bla'
prints "bla bla 0,5 bla bla".

Please explain this behaviour if it is intended. The code which demonstrates the problem using say and print statements is below. I use Strawberry Perl 5.10 on Windows XP SP3.
use strict; use warnings; use diagnostics; use v5.10; use locale; use POSIX qw(locale_h); setlocale (LC_ALL, "german") or die "failed to load locale!"; my $number = 1/2; say 'output of say'; say $number; say 1/2; say 1/2 . " concatenate"; say 1/2 , " list"; say "1/2 concatenate"; say "1/2 list"; say $number . " concatenate"; say $number , " list"; say 'output of print'; print "$number\n"; print 1/2 . "\n"; print 1/2 . " concatenate\n"; print 1/2 , " list\n"; print "1/2 concatenate\n"; print "1/2 list\n"; print $number . " concatenate\n"; print $number , " list\n";
this prints on my machine:
output of say 0,5 0,5 0.5 concatenate 0,5 list 1/2 concatenate 1/2 list 0,5 concatenate 0,5 list output of print 0,5 0.5 0.5 concatenate 0,5 list 1/2 concatenate 1/2 list

Replies are listed 'Best First'.
Re: please explain print/say behavior with setlocale
by almut (Canon) on Mar 30, 2010 at 11:19 UTC

    Localization (or more precisely, LC_NUMERIC here) applies to numeric values being output.  Stringification, OTOH, as it happens in something like print 1/2 . "\n" before outputting the value, isn't always subject to localization* ...  And when you write print "1/2\n" etc., it's not represented as a number in the first place.

    ___

    * update: interpolation and concatenation of numeric values stored in a variable apparently does localize:

    setlocale LC_NUMERIC, "german"; $n = 1/2; print "$n\n"; # 0,5 print $n . "\n"; # 0,5 print 1/2 ."\n"; # 0.5

    My guess would be this has to do with compile-time vs. run-time effects, i.e. the 1/2 in 1/2 . "\n" is being processed at compile-time without the locale setting having been modified yet, unless you put the setlocale in a BEGIN {} block...

      sorry, I don't understand why the output isn't represented like a number in case of print 1/2 . "\n" the output "0.5<newline>" looks like a number exactly like a division result of 1 divided by 2. And if it is a number it should be displayed using comma as german floating separator. In opposite it is very clear to me why print "1/2\n" produces "1/2<newline>" output - I feel completely fine with it.
      This is where I got stuck. Why
      $n = 1 / 2; print $n . "\n"; # 0,5 is different to print 1/2 ."\n"; # 0.5

        See my update as to compile-time vs. run-time.  IOW, when you write

        BEGIN { setlocale LC_NUMERIC, "german"; } $n = 1 / 2; print $n . "\n"; # 0,5 print 1/2 ."\n"; # 0,5

        you get localized output in both cases, because localization is already in effect at compile-time.

Re: please explain print/say behavior with setlocale
by rovf (Priest) on Mar 30, 2010 at 11:03 UTC
    I don't exactly understand your problem. You activate German locale, so "," is used instead of "." when outputting fractional values. This is exactly how locales are intended to be. What kind of output would you have expected?

    -- 
    Ronald Fischer <ynnor@mm.st>
      My problem is the "." which is used sometimes e.g. say 1/2 . " concatenate" produces "0.5 concatenate" and not "0,5 concatenate". I would expect to see the second one as it correctly displayed using say 1/2 , " concatenate".