Skip Menu |

This queue is for tickets about the i18n CPAN distribution.

Report information
The Basics
Id: 14705
Status: resolved
Priority: 0/
Queue: i18n

People
Owner: Nobody in particular
Requestors: steve.hay [...] uk.radan.com
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 0.07
Fixed in: (no value)



Subject: i18n doesn't seem to work at all in modules
I'm running perl-5.8.7 on Windows XP in UK English. Create the following two files in C:\Temp\i18n :- Foo.pm ------ package Foo; use i18n 'C:/Temp/i18n'; sub foo { print ~~'Test' } 1; en.po ----- msgid "Test" msgstr "English" Now "cd" to that directory and run "perl -MFoo -e "Foo::foo()". The output is "Test". It should be "English". (I18N::LangTags::Detect::detect() returns ('en-gb') on my system.) The i18n pragma does seem to work OK in scripts, though. For example, create the following file in the same directory:- test.pl ------- use i18n 'C:/Temp/i18n'; print ~~'Test'; and then run "perl test.pl" and the output is "English" as expected. (One-liners also work fine, e.g. perl -Mi18n=. -e "print ~~'Test'" also produces "English".) I couldn't figure out at a quick glance why it doesn't work in modules, but clearly this is a real bummer.
Surprise! It's only been (not quite) 14 years, and I'm not the maintainer (nor do I wish to be). I hope you haven't been holding your breath... But I was looking for a module, stumbled across this and was curious. The issue is that i18n is very careful about localizing. Too careful. i18n assumes that only the module that creates a string will need the localized version. What's happening here is that while Foo creates the string (and sets up the localization object), main tries to stringify it for print (due to stack frame optimizations). main isn't Foo, so i18n punts. The same thing would happen if a module returned a localized string to a caller that then tried to print (or otherwise stringify) it. I don't see why this assumption was made... The fix appears to be this - I haven't done testing beyond your test case, so it may not be complete. in i18n.pm::_do_loc, 4 lines in: ( $pkg eq caller ) and my $loc = $pkg->can('loc') or return ~"$_[0]" should not be checking caller. So replace with: my $loc = $pkg->can('loc') or return ~"$_[0]" and your test case will work. It looks to me as of that's the only case of this excessive paranoia - but I could be wrong. Perhaps someone will eventually adopt this module and release a fix. But don't hold your breath :-)
Merged and published as i18n 0.13 on CPAN (and now on GitHub too: https://github.com/audreyt/i18n-pm ) Thank you for the contribution! Cheers, Audrey On Tue Apr 30 11:42:23 2019, tlhackque wrote: Show quoted text
> Surprise! > > It's only been (not quite) 14 years, and I'm not the maintainer (nor > do I wish to be). > > I hope you haven't been holding your breath... > > But I was looking for a module, stumbled across this and was curious. > > The issue is that i18n is very careful about localizing. Too careful. > > i18n assumes that only the module that creates a string will need the > localized version. What's happening here is that while Foo creates > the string (and sets up the localization object), main tries to > stringify it for print (due to stack frame optimizations). main isn't > Foo, so i18n punts. The same thing would happen if a module returned > a localized string to a caller that then tried to print (or otherwise > stringify) it. I don't see why this assumption was made... > > The fix appears to be this - I haven't done testing beyond your test > case, so it may not be complete. > > in i18n.pm::_do_loc, 4 lines in: > > ( $pkg eq caller ) and my $loc = $pkg->can('loc') > or return ~"$_[0]" > > should not be checking caller. So replace with: > my $loc = $pkg->can('loc') > or return ~"$_[0]" > > and your test case will work. > > It looks to me as of that's the only case of this excessive paranoia - > but I could be wrong. > > Perhaps someone will eventually adopt this module and release a fix. > > But don't hold your breath :-)