gettext: Perl Pitfalls

1 
1 15.5.18.9 Bugs, Pitfalls, And Things That Do Not Work
1 .....................................................
1 
1    The foregoing sections should have proven that ‘xgettext’ is quite
1 smart in extracting translatable strings from Perl sources.  Yet, some
1 more or less exotic constructs that could be expected to work, actually
1 do not work.
1 
1    One of the more relevant limitations can be found in the
1 implementation of variable interpolation inside quoted strings.  Only
1 simple hash lookups can be used there:
1 
1      print <<EOF;
1      $gettext{"The dot operator"
1                . " does not work"
1                . "here!"}
1      Likewise, you cannot @{[ gettext ("interpolate function calls") ]}
1      inside quoted strings or quote-like expressions.
1      EOF
1 
1    This is valid Perl code and will actually trigger invocations of the
1 ‘gettext’ function at runtime.  Yet, the Perl parser in ‘xgettext’ will
1 fail to recognize the strings.  A less obvious example can be found in
1 the interpolation of regular expressions:
1 
1      s/<!--START_OF_WEEK-->/gettext ("Sunday")/e;
1 
1    The modifier ‘e’ will cause the substitution to be interpreted as an
1 evaluable statement.  Consequently, at runtime the function ‘gettext()’
1 is called, but again, the parser fails to extract the string “Sunday”.
1 Use a temporary variable as a simple workaround if you really happen to
1 need this feature:
1 
1      my $sunday = gettext "Sunday";
1      s/<!--START_OF_WEEK-->/$sunday/;
1 
1    Hash slices would also be handy but are not recognized:
1 
1      my @weekdays = @gettext{'Sunday', 'Monday', 'Tuesday', 'Wednesday',
1                              'Thursday', 'Friday', 'Saturday'};
1      # Or even:
1      @weekdays = @gettext{qw (Sunday Monday Tuesday Wednesday Thursday
1                               Friday Saturday) };
1 
1    This is perfectly valid usage of the tied hash ‘%gettext’ but the
1 strings are not recognized and therefore will not be extracted.
1 
1    Another caveat of the current version is its rudimentary support for
1 non-ASCII characters in identifiers.  You may encounter serious problems
1 if you use identifiers with characters outside the range of ’A’-’Z’,
1 ’a’-’z’, ’0’-’9’ and the underscore ’_’.
1 
1    Maybe some of these missing features will be implemented in future
1 versions, but since you can always make do without them at minimal
1 effort, these todos have very low priority.
1 
1    A nasty problem are brace format strings that already contain braces
1 as part of the normal text, for example the usage strings typically
1 encountered in programs:
1 
1      die "usage: $0 {OPTIONS} FILENAME...\n";
1 
1    If you want to internationalize this code with Perl brace format
1 strings, you will run into a problem:
1 
1      die __x ("usage: {program} {OPTIONS} FILENAME...\n", program => $0);
1 
1    Whereas ‘{program}’ is a placeholder, ‘{OPTIONS}’ is not and should
1 probably be translated.  Yet, there is no way to teach the Perl parser
1 in ‘xgettext’ to recognize the first one, and leave the other one alone.
1 
1    There are two possible work-arounds for this problem.  If you are
1 sure that your program will run under Perl 5.8.0 or newer (these Perl
1 versions handle positional parameters in ‘printf()’) or if you are sure
1 that the translator will not have to reorder the arguments in her
1 translation – for example if you have only one brace placeholder in your
1 string, or if it describes a syntax, like in this one –, you can mark
1 the string as ‘no-perl-brace-format’ and use ‘printf()’:
1 
1      # xgettext: no-perl-brace-format
1      die sprintf ("usage: %s {OPTIONS} FILENAME...\n", $0);
1 
1    If you want to use the more portable Perl brace format, you will have
1 to do put placeholders in place of the literal braces:
1 
1      die __x ("usage: {program} {[}OPTIONS{]} FILENAME...\n",
1               program => $0, '[' => '{', ']' => '}');
1 
1    Perl brace format strings know no escaping mechanism.  No matter how
1 this escaping mechanism looked like, it would either give the programmer
1 a hard time, make translating Perl brace format strings heavy-going, or
1 result in a performance penalty at runtime, when the format directives
1 get executed.  Most of the time you will happily get along with
1 ‘printf()’ for this special case.
1