| Filename | /usr/share/perl/5.36/Locale/Maketext/Simple.pm |
| Statements | Executed 66 statements in 1.14ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 3 | 1 | 1 | 180µs | 201µs | Locale::Maketext::Simple::load_loc |
| 3 | 3 | 3 | 53µs | 289µs | Locale::Maketext::Simple::import |
| 3 | 1 | 1 | 9µs | 9µs | Locale::Maketext::Simple::default_loc |
| 1 | 1 | 1 | 7µs | 8µs | Locale::Maketext::Simple::BEGIN@4 |
| 1 | 1 | 1 | 6µs | 6µs | Locale::Maketext::Simple::BEGIN@5 |
| 1 | 1 | 1 | 4µs | 8µs | Locale::Maketext::Simple::BEGIN@122 |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:124] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:176] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:197] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:205] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:219] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::_default_gettext |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::_escape |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::_unescape |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::auto_path |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::reload_loc |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Locale::Maketext::Simple; | ||||
| 2 | 1 | 300ns | $Locale::Maketext::Simple::VERSION = '0.21_01'; | ||
| 3 | |||||
| 4 | 2 | 16µs | 2 | 9µs | # spent 8µs (7+1) within Locale::Maketext::Simple::BEGIN@4 which was called:
# once (7µs+1µs) by Params::Check::BEGIN@6 at line 4 # spent 8µs making 1 call to Locale::Maketext::Simple::BEGIN@4
# spent 1µs making 1 call to strict::import |
| 5 | 2 | 83µs | 1 | 6µs | # spent 6µs within Locale::Maketext::Simple::BEGIN@5 which was called:
# once (6µs+0s) by Params::Check::BEGIN@6 at line 5 # spent 6µs making 1 call to Locale::Maketext::Simple::BEGIN@5 |
| 6 | |||||
| 7 | =head1 NAME | ||||
| 8 | |||||
| 9 | Locale::Maketext::Simple - Simple interface to Locale::Maketext::Lexicon | ||||
| 10 | |||||
| 11 | =head1 VERSION | ||||
| 12 | |||||
| 13 | This document describes version 0.18 of Locale::Maketext::Simple, | ||||
| 14 | released Septermber 8, 2006. | ||||
| 15 | |||||
| 16 | =head1 SYNOPSIS | ||||
| 17 | |||||
| 18 | Minimal setup (looks for F<auto/Foo/*.po> and F<auto/Foo/*.mo>): | ||||
| 19 | |||||
| 20 | package Foo; | ||||
| 21 | use Locale::Maketext::Simple; # exports 'loc' | ||||
| 22 | loc_lang('fr'); # set language to French | ||||
| 23 | sub hello { | ||||
| 24 | print loc("Hello, [_1]!", "World"); | ||||
| 25 | } | ||||
| 26 | |||||
| 27 | More sophisticated example: | ||||
| 28 | |||||
| 29 | package Foo::Bar; | ||||
| 30 | use Locale::Maketext::Simple ( | ||||
| 31 | Class => 'Foo', # search in auto/Foo/ | ||||
| 32 | Style => 'gettext', # %1 instead of [_1] | ||||
| 33 | Export => 'maketext', # maketext() instead of loc() | ||||
| 34 | Subclass => 'L10N', # Foo::L10N instead of Foo::I18N | ||||
| 35 | Decode => 1, # decode entries to unicode-strings | ||||
| 36 | Encoding => 'locale', # but encode lexicons in current locale | ||||
| 37 | # (needs Locale::Maketext::Lexicon 0.36) | ||||
| 38 | ); | ||||
| 39 | sub japh { | ||||
| 40 | print maketext("Just another %1 hacker", "Perl"); | ||||
| 41 | } | ||||
| 42 | |||||
| 43 | =head1 DESCRIPTION | ||||
| 44 | |||||
| 45 | This module is a simple wrapper around B<Locale::Maketext::Lexicon>, | ||||
| 46 | designed to alleviate the need of creating I<Language Classes> for | ||||
| 47 | module authors. | ||||
| 48 | |||||
| 49 | The language used is chosen from the loc_lang call. If a lookup is not | ||||
| 50 | possible, the i-default language will be used. If the lookup is not in the | ||||
| 51 | i-default language, then the key will be returned. | ||||
| 52 | |||||
| 53 | If B<Locale::Maketext::Lexicon> is not present, it implements a | ||||
| 54 | minimal localization function by simply interpolating C<[_1]> with | ||||
| 55 | the first argument, C<[_2]> with the second, etc. Interpolated | ||||
| 56 | function like C<[quant,_1]> are treated as C<[_1]>, with the sole | ||||
| 57 | exception of C<[tense,_1,X]>, which will append C<ing> to C<_1> when | ||||
| 58 | X is C<present>, or appending C<ed> to <_1> otherwise. | ||||
| 59 | |||||
| 60 | =head1 OPTIONS | ||||
| 61 | |||||
| 62 | All options are passed either via the C<use> statement, or via an | ||||
| 63 | explicit C<import>. | ||||
| 64 | |||||
| 65 | =head2 Class | ||||
| 66 | |||||
| 67 | By default, B<Locale::Maketext::Simple> draws its source from the | ||||
| 68 | calling package's F<auto/> directory; you can override this behaviour | ||||
| 69 | by explicitly specifying another package as C<Class>. | ||||
| 70 | |||||
| 71 | =head2 Path | ||||
| 72 | |||||
| 73 | If your PO and MO files are under a path elsewhere than C<auto/>, | ||||
| 74 | you may specify it using the C<Path> option. | ||||
| 75 | |||||
| 76 | =head2 Style | ||||
| 77 | |||||
| 78 | By default, this module uses the C<maketext> style of C<[_1]> and | ||||
| 79 | C<[quant,_1]> for interpolation. Alternatively, you can specify the | ||||
| 80 | C<gettext> style, which uses C<%1> and C<%quant(%1)> for interpolation. | ||||
| 81 | |||||
| 82 | This option is case-insensitive. | ||||
| 83 | |||||
| 84 | =head2 Export | ||||
| 85 | |||||
| 86 | By default, this module exports a single function, C<loc>, into its | ||||
| 87 | caller's namespace. You can set it to another name, or set it to | ||||
| 88 | an empty string to disable exporting. | ||||
| 89 | |||||
| 90 | =head2 Subclass | ||||
| 91 | |||||
| 92 | By default, this module creates an C<::I18N> subclass under the | ||||
| 93 | caller's package (or the package specified by C<Class>), and stores | ||||
| 94 | lexicon data in its subclasses. You can assign a name other than | ||||
| 95 | C<I18N> via this option. | ||||
| 96 | |||||
| 97 | =head2 Decode | ||||
| 98 | |||||
| 99 | If set to a true value, source entries will be converted into | ||||
| 100 | utf8-strings (available in Perl 5.6.1 or later). This feature | ||||
| 101 | needs the B<Encode> or B<Encode::compat> module. | ||||
| 102 | |||||
| 103 | =head2 Encoding | ||||
| 104 | |||||
| 105 | Specifies an encoding to store lexicon entries, instead of | ||||
| 106 | utf8-strings. If set to C<locale>, the encoding from the current | ||||
| 107 | locale setting is used. Implies a true value for C<Decode>. | ||||
| 108 | |||||
| 109 | =cut | ||||
| 110 | |||||
| 111 | # spent 289µs (53+236) within Locale::Maketext::Simple::import which was called 3 times, avg 96µs/call:
# once (17µs+87µs) by IPC::Cmd::BEGIN@62 at line 62 of IPC/Cmd.pm
# once (19µs+76µs) by Params::Check::BEGIN@6 at line 6 of Params/Check.pm
# once (16µs+73µs) by Module::Load::Conditional::BEGIN@7 at line 7 of Module/Load/Conditional.pm | ||||
| 112 | 3 | 3µs | my ($class, %args) = @_; | ||
| 113 | |||||
| 114 | 3 | 4µs | 3 | 14µs | $args{Class} ||= caller; # spent 14µs making 3 calls to Contextual::Return::__ANON__[Contextual/Return.pm:30], avg 5µs/call |
| 115 | 3 | 700ns | $args{Style} ||= 'maketext'; | ||
| 116 | 3 | 1µs | $args{Export} ||= 'loc'; | ||
| 117 | 3 | 1µs | $args{Subclass} ||= 'I18N'; | ||
| 118 | |||||
| 119 | 3 | 5µs | 3 | 201µs | my ($loc, $loc_lang) = $class->load_loc(%args); # spent 201µs making 3 calls to Locale::Maketext::Simple::load_loc, avg 67µs/call |
| 120 | 3 | 5µs | 3 | 9µs | $loc ||= $class->default_loc(%args); # spent 9µs making 3 calls to Locale::Maketext::Simple::default_loc, avg 3µs/call |
| 121 | |||||
| 122 | 2 | 807µs | 2 | 12µs | # spent 8µs (4+4) within Locale::Maketext::Simple::BEGIN@122 which was called:
# once (4µs+4µs) by Params::Check::BEGIN@6 at line 122 # spent 8µs making 1 call to Locale::Maketext::Simple::BEGIN@122
# spent 4µs making 1 call to strict::unimport |
| 123 | 3 | 9µs | 3 | 8µs | *{caller(0) . "::$args{Export}"} = $loc if $args{Export}; # spent 8µs making 3 calls to Contextual::Return::__ANON__[Contextual/Return.pm:30], avg 3µs/call |
| 124 | 3 | 15µs | 3 | 5µs | *{caller(0) . "::$args{Export}_lang"} = $loc_lang || sub { 1 }; # spent 5µs making 3 calls to Contextual::Return::__ANON__[Contextual/Return.pm:30], avg 2µs/call |
| 125 | } | ||||
| 126 | |||||
| 127 | 1 | 100ns | my %Loc; | ||
| 128 | |||||
| 129 | sub reload_loc { %Loc = () } | ||||
| 130 | |||||
| 131 | # spent 201µs (180+20) within Locale::Maketext::Simple::load_loc which was called 3 times, avg 67µs/call:
# 3 times (180µs+20µs) by Locale::Maketext::Simple::import at line 119, avg 67µs/call | ||||
| 132 | 3 | 2µs | my ($class, %args) = @_; | ||
| 133 | |||||
| 134 | 3 | 6µs | my $pkg = join('::', grep { defined and length } $args{Class}, $args{Subclass}); | ||
| 135 | 3 | 600ns | return $Loc{$pkg} if exists $Loc{$pkg}; | ||
| 136 | |||||
| 137 | 3 | 600ns | eval { | ||
| 138 | 3 | 4µs | local @INC = @INC; | ||
| 139 | 3 | 700ns | pop @INC if $INC[-1] eq '.'; | ||
| 140 | 3 | 167µs | 3 | 20µs | require Locale::Maketext::Lexicon; # spent 20µs making 3 calls to diagnostics::death_trap, avg 7µs/call |
| 141 | 1 | ||||
| 142 | } or return; | ||||
| 143 | $Locale::Maketext::Lexicon::VERSION > 0.20 or return; | ||||
| 144 | eval { require File::Spec; 1 } or return; | ||||
| 145 | |||||
| 146 | my $path = $args{Path} || $class->auto_path($args{Class}) or return; | ||||
| 147 | my $pattern = File::Spec->catfile($path, '*.[pm]o'); | ||||
| 148 | my $decode = $args{Decode} || 0; | ||||
| 149 | my $encoding = $args{Encoding} || undef; | ||||
| 150 | |||||
| 151 | $decode = 1 if $encoding; | ||||
| 152 | |||||
| 153 | $pattern =~ s{\\}{/}g; # to counter win32 paths | ||||
| 154 | |||||
| 155 | eval " | ||||
| 156 | package $pkg; | ||||
| 157 | use base 'Locale::Maketext'; | ||||
| 158 | Locale::Maketext::Lexicon->import({ | ||||
| 159 | 'i-default' => [ 'Auto' ], | ||||
| 160 | '*' => [ Gettext => \$pattern ], | ||||
| 161 | _decode => \$decode, | ||||
| 162 | _encoding => \$encoding, | ||||
| 163 | }); | ||||
| 164 | *${pkg}::Lexicon = \\%${pkg}::i_default::Lexicon; | ||||
| 165 | *tense = sub { \$_[1] . ((\$_[2] eq 'present') ? 'ing' : 'ed') } | ||||
| 166 | unless defined &tense; | ||||
| 167 | |||||
| 168 | 1; | ||||
| 169 | " or die $@; | ||||
| 170 | |||||
| 171 | my $lh = eval { $pkg->get_handle } or return; | ||||
| 172 | my $style = lc($args{Style}); | ||||
| 173 | if ($style eq 'maketext') { | ||||
| 174 | $Loc{$pkg} = sub { | ||||
| 175 | $lh->maketext(@_) | ||||
| 176 | }; | ||||
| 177 | } | ||||
| 178 | elsif ($style eq 'gettext') { | ||||
| 179 | $Loc{$pkg} = sub { | ||||
| 180 | my $str = shift; | ||||
| 181 | $str =~ s{([\~\[\]])}{~$1}g; | ||||
| 182 | $str =~ s{ | ||||
| 183 | $1 ? $1 | ||||
| 184 | : $2 ? "\[$2,"._unescape($3)."]" | ||||
| 185 | : "[_$4]" | ||||
| 186 | }egx; | ||||
| 187 | \(([^\)]*)\) # 3 - arguments | ||||
| 188 | | | ||||
| 189 | ([1-9]\d*|\*) # 4 - variable | ||||
| 190 | ) | ||||
| 191 | }{ | ||||
| 192 | |||||
| - - | |||||
| 196 | return $lh->maketext($str, @_); | ||||
| 197 | }; | ||||
| 198 | } | ||||
| 199 | else { | ||||
| 200 | die "Unknown Style: $style"; | ||||
| 201 | } | ||||
| 202 | |||||
| 203 | return $Loc{$pkg}, sub { | ||||
| 204 | $lh = $pkg->get_handle(@_); | ||||
| 205 | }; | ||||
| 206 | } | ||||
| 207 | |||||
| 208 | # spent 9µs within Locale::Maketext::Simple::default_loc which was called 3 times, avg 3µs/call:
# 3 times (9µs+0s) by Locale::Maketext::Simple::import at line 120, avg 3µs/call | ||||
| 209 | 3 | 2µs | my ($self, %args) = @_; | ||
| 210 | 3 | 2µs | my $style = lc($args{Style}); | ||
| 211 | 3 | 6µs | if ($style eq 'maketext') { | ||
| 212 | return sub { | ||||
| 213 | my $str = shift; | ||||
| 214 | $str =~ s{((?<!~)(?:~~)*)\[_([1-9]\d*|\*)\]} | ||||
| 215 | {$1%$2}g; | ||||
| 216 | $str =~ s{((?<!~)(?:~~)*)\[([A-Za-z#*]\w*),([^\]]+)\]} | ||||
| 217 | {"$1%$2(" . _escape($3) . ')'}eg; | ||||
| 218 | _default_gettext($str, @_); | ||||
| 219 | }; | ||||
| 220 | } | ||||
| 221 | elsif ($style eq 'gettext') { | ||||
| 222 | return \&_default_gettext; | ||||
| 223 | } | ||||
| 224 | else { | ||||
| 225 | die "Unknown Style: $style"; | ||||
| 226 | } | ||||
| 227 | } | ||||
| 228 | |||||
| 229 | sub _default_gettext { | ||||
| 230 | my $str = shift; | ||||
| 231 | $str =~ s{ | ||||
| 232 | my $digit = $2 || shift; | ||||
| 233 | $digit . ( | ||||
| 234 | $1 ? ( | ||||
| 235 | ($1 eq 'tense') ? (($3 eq 'present') ? 'ing' : 'ed') : | ||||
| 236 | ($1 eq 'quant') ? ' ' . (($digit > 1) ? ($4 || "$3s") : $3) : | ||||
| 237 | '' | ||||
| 238 | ) : '' | ||||
| 239 | ); | ||||
| 240 | }egx; | ||||
| 241 | ) # end either | ||||
| 242 | (?: # maybe followed | ||||
| 243 | , # by a comma | ||||
| 244 | ([^),]*) # and a param -- 3 | ||||
| 245 | )? # end maybe | ||||
| 246 | (?: # maybe followed | ||||
| 247 | , # by another comma | ||||
| 248 | ([^),]*) # and a param -- 4 | ||||
| 249 | )? # end maybe | ||||
| 250 | [^)]* # and other ignorable params | ||||
| 251 | \) # closing function call | ||||
| 252 | ) # closing either one of | ||||
| 253 | }{ | ||||
| 254 | |||||
| - - | |||||
| 263 | return $str; | ||||
| 264 | }; | ||||
| 265 | |||||
| 266 | sub _escape { | ||||
| 267 | my $text = shift; | ||||
| 268 | $text =~ s/\b_([1-9]\d*)/%$1/g; | ||||
| 269 | return $text; | ||||
| 270 | } | ||||
| 271 | |||||
| 272 | sub _unescape { | ||||
| 273 | join(',', map { | ||||
| 274 | /\A(\s*)%([1-9]\d*|\*)(\s*)\z/ ? "$1_$2$3" : $_ | ||||
| 275 | } split(/,/, $_[0])); | ||||
| 276 | } | ||||
| 277 | |||||
| 278 | sub auto_path { | ||||
| 279 | my ($self, $calldir) = @_; | ||||
| 280 | $calldir =~ s#::#/#g; | ||||
| 281 | my $path = $INC{$calldir . '.pm'} or return; | ||||
| 282 | |||||
| 283 | # Try absolute path name. | ||||
| 284 | if ($^O eq 'MacOS') { | ||||
| 285 | (my $malldir = $calldir) =~ tr#/#:#; | ||||
| 286 | $path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:#s; | ||||
| 287 | } else { | ||||
| 288 | $path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/#; | ||||
| 289 | } | ||||
| 290 | |||||
| 291 | return $path if -d $path; | ||||
| 292 | |||||
| 293 | # If that failed, try relative path with normal @INC searching. | ||||
| 294 | $path = "auto/$calldir/"; | ||||
| 295 | foreach my $inc (@INC) { | ||||
| 296 | return "$inc/$path" if -d "$inc/$path"; | ||||
| 297 | } | ||||
| 298 | |||||
| 299 | return; | ||||
| 300 | } | ||||
| 301 | |||||
| 302 | 1 | 2µs | 1; | ||
| 303 | |||||
| 304 | =head1 ACKNOWLEDGMENTS | ||||
| 305 | |||||
| 306 | Thanks to Jos I. Boumans for suggesting this module to be written. | ||||
| 307 | |||||
| 308 | Thanks to Chia-Liang Kao for suggesting C<Path> and C<loc_lang>. | ||||
| 309 | |||||
| 310 | =head1 SEE ALSO | ||||
| 311 | |||||
| 312 | L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | ||||
| 313 | |||||
| 314 | =head1 AUTHORS | ||||
| 315 | |||||
| 316 | Audrey Tang E<lt>cpan@audreyt.orgE<gt> | ||||
| 317 | |||||
| 318 | =head1 COPYRIGHT | ||||
| 319 | |||||
| 320 | Copyright 2003, 2004, 2005, 2006 by Audrey Tang E<lt>cpan@audreyt.orgE<gt>. | ||||
| 321 | |||||
| 322 | This software is released under the MIT license cited below. Additionally, | ||||
| 323 | when this software is distributed with B<Perl Kit, Version 5>, you may also | ||||
| 324 | redistribute it and/or modify it under the same terms as Perl itself. | ||||
| 325 | |||||
| 326 | =head2 The "MIT" License | ||||
| 327 | |||||
| 328 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| 329 | of this software and associated documentation files (the "Software"), to deal | ||||
| 330 | in the Software without restriction, including without limitation the rights | ||||
| 331 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| 332 | copies of the Software, and to permit persons to whom the Software is | ||||
| 333 | furnished to do so, subject to the following conditions: | ||||
| 334 | |||||
| 335 | The above copyright notice and this permission notice shall be included in | ||||
| 336 | all copies or substantial portions of the Software. | ||||
| 337 | |||||
| 338 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||||
| 339 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| 340 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||||
| 341 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| 342 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
| 343 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
| 344 | DEALINGS IN THE SOFTWARE. | ||||
| 345 | |||||
| 346 | =cut |