| Filename | /usr/share/perl/5.20/Locale/Maketext/Simple.pm |
| Statements | Executed 93 statements in 3.28ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 2 | 1 | 1 | 2.64ms | 3.95ms | Locale::Maketext::Simple::load_loc |
| 22 | 2 | 1 | 1.09ms | 1.09ms | Locale::Maketext::Simple::CORE:ftdir (opcode) |
| 2 | 1 | 1 | 95µs | 1.23ms | Locale::Maketext::Simple::auto_path |
| 2 | 2 | 2 | 45µs | 4.01ms | Locale::Maketext::Simple::import |
| 2 | 1 | 1 | 24µs | 24µs | Locale::Maketext::Simple::CORE:regcomp (opcode) |
| 4 | 2 | 1 | 14µs | 14µs | Locale::Maketext::Simple::CORE:subst (opcode) |
| 1 | 1 | 1 | 12µs | 23µs | Locale::Maketext::Simple::BEGIN@4 |
| 1 | 1 | 1 | 11µs | 11µs | Locale::Maketext::Simple::BEGIN@5 |
| 2 | 1 | 1 | 10µs | 10µs | Locale::Maketext::Simple::default_loc |
| 1 | 1 | 1 | 6µs | 14µs | Locale::Maketext::Simple::BEGIN@122 |
| 4 | 1 | 1 | 4µs | 4µs | Locale::Maketext::Simple::CORE:substcont (opcode) |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:124] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:171] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:192] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:200] |
| 0 | 0 | 0 | 0s | 0s | Locale::Maketext::Simple::__ANON__[:214] |
| 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::reload_loc |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Locale::Maketext::Simple; | ||||
| 2 | 1 | 500ns | $Locale::Maketext::Simple::VERSION = '0.21'; | ||
| 3 | |||||
| 4 | 2 | 22µs | 2 | 34µs | # spent 23µs (12+11) within Locale::Maketext::Simple::BEGIN@4 which was called:
# once (12µs+11µs) by Params::Check::BEGIN@6 at line 4 # spent 23µs making 1 call to Locale::Maketext::Simple::BEGIN@4
# spent 11µs making 1 call to strict::import |
| 5 | 2 | 134µs | 1 | 11µs | # spent 11µs within Locale::Maketext::Simple::BEGIN@5 which was called:
# once (11µs+0s) by Params::Check::BEGIN@6 at line 5 # spent 11µ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 4.01ms (45µs+3.96) within Locale::Maketext::Simple::import which was called 2 times, avg 2.00ms/call:
# once (25µs+3.34ms) by Params::Check::BEGIN@6 at line 6 of Params/Check.pm
# once (19µs+627µs) by Module::Load::Conditional::BEGIN@7 at line 7 of Module/Load/Conditional.pm | ||||
| 112 | 2 | 2µs | my ($class, %args) = @_; | ||
| 113 | |||||
| 114 | 2 | 2µs | $args{Class} ||= caller; | ||
| 115 | 2 | 400ns | $args{Style} ||= 'maketext'; | ||
| 116 | 2 | 500ns | $args{Export} ||= 'loc'; | ||
| 117 | 2 | 300ns | $args{Subclass} ||= 'I18N'; | ||
| 118 | |||||
| 119 | 2 | 5µs | 2 | 3.95ms | my ($loc, $loc_lang) = $class->load_loc(%args); # spent 3.95ms making 2 calls to Locale::Maketext::Simple::load_loc, avg 1.98ms/call |
| 120 | 2 | 7µs | 2 | 10µs | $loc ||= $class->default_loc(%args); # spent 10µs making 2 calls to Locale::Maketext::Simple::default_loc, avg 5µs/call |
| 121 | |||||
| 122 | 2 | 1.10ms | 2 | 23µs | # spent 14µs (6+8) within Locale::Maketext::Simple::BEGIN@122 which was called:
# once (6µs+8µs) by Params::Check::BEGIN@6 at line 122 # spent 14µs making 1 call to Locale::Maketext::Simple::BEGIN@122
# spent 8µs making 1 call to strict::unimport |
| 123 | 2 | 8µs | *{caller(0) . "::$args{Export}"} = $loc if $args{Export}; | ||
| 124 | 2 | 19µs | *{caller(0) . "::$args{Export}_lang"} = $loc_lang || sub { 1 }; | ||
| 125 | } | ||||
| 126 | |||||
| 127 | 1 | 200ns | my %Loc; | ||
| 128 | |||||
| 129 | sub reload_loc { %Loc = () } | ||||
| 130 | |||||
| 131 | # spent 3.95ms (2.64+1.31) within Locale::Maketext::Simple::load_loc which was called 2 times, avg 1.98ms/call:
# 2 times (2.64ms+1.31ms) by Locale::Maketext::Simple::import at line 119, avg 1.98ms/call | ||||
| 132 | 2 | 2µs | my ($class, %args) = @_; | ||
| 133 | |||||
| 134 | 2 | 7µs | my $pkg = join('::', grep { defined and length } $args{Class}, $args{Subclass}); | ||
| 135 | 2 | 500ns | return $Loc{$pkg} if exists $Loc{$pkg}; | ||
| 136 | |||||
| 137 | 6 | 711µs | eval { require Locale::Maketext::Lexicon; 1 } or return; | ||
| 138 | 2 | 2µs | $Locale::Maketext::Lexicon::VERSION > 0.20 or return; | ||
| 139 | 6 | 2µs | eval { require File::Spec; 1 } or return; | ||
| 140 | |||||
| 141 | 2 | 10µs | 2 | 1.23ms | my $path = $args{Path} || $class->auto_path($args{Class}) or return; # spent 1.23ms making 2 calls to Locale::Maketext::Simple::auto_path, avg 614µs/call |
| 142 | my $pattern = File::Spec->catfile($path, '*.[pm]o'); | ||||
| 143 | my $decode = $args{Decode} || 0; | ||||
| 144 | my $encoding = $args{Encoding} || undef; | ||||
| 145 | |||||
| 146 | $decode = 1 if $encoding; | ||||
| 147 | |||||
| 148 | $pattern =~ s{\\}{/}g; # to counter win32 paths | ||||
| 149 | |||||
| 150 | eval " | ||||
| 151 | package $pkg; | ||||
| 152 | use base 'Locale::Maketext'; | ||||
| 153 | Locale::Maketext::Lexicon->import({ | ||||
| 154 | 'i-default' => [ 'Auto' ], | ||||
| 155 | '*' => [ Gettext => \$pattern ], | ||||
| 156 | _decode => \$decode, | ||||
| 157 | _encoding => \$encoding, | ||||
| 158 | }); | ||||
| 159 | *${pkg}::Lexicon = \\%${pkg}::i_default::Lexicon; | ||||
| 160 | *tense = sub { \$_[1] . ((\$_[2] eq 'present') ? 'ing' : 'ed') } | ||||
| 161 | unless defined &tense; | ||||
| 162 | |||||
| 163 | 1; | ||||
| 164 | " or die $@; | ||||
| 165 | |||||
| 166 | my $lh = eval { $pkg->get_handle } or return; | ||||
| 167 | my $style = lc($args{Style}); | ||||
| 168 | if ($style eq 'maketext') { | ||||
| 169 | $Loc{$pkg} = sub { | ||||
| 170 | $lh->maketext(@_) | ||||
| 171 | }; | ||||
| 172 | } | ||||
| 173 | elsif ($style eq 'gettext') { | ||||
| 174 | $Loc{$pkg} = sub { | ||||
| 175 | my $str = shift; | ||||
| 176 | $str =~ s{([\~\[\]])}{~$1}g; | ||||
| 177 | $str =~ s{ | ||||
| 178 | $1 ? $1 | ||||
| 179 | : $2 ? "\[$2,"._unescape($3)."]" | ||||
| 180 | : "[_$4]" | ||||
| 181 | }egx; | ||||
| 182 | \(([^\)]*)\) # 3 - arguments | ||||
| 183 | | | ||||
| 184 | ([1-9]\d*|\*) # 4 - variable | ||||
| 185 | ) | ||||
| 186 | }{ | ||||
| 187 | |||||
| - - | |||||
| 191 | return $lh->maketext($str, @_); | ||||
| 192 | }; | ||||
| 193 | } | ||||
| 194 | else { | ||||
| 195 | die "Unknown Style: $style"; | ||||
| 196 | } | ||||
| 197 | |||||
| 198 | return $Loc{$pkg}, sub { | ||||
| 199 | $lh = $pkg->get_handle(@_); | ||||
| 200 | }; | ||||
| 201 | } | ||||
| 202 | |||||
| 203 | # spent 10µs within Locale::Maketext::Simple::default_loc which was called 2 times, avg 5µs/call:
# 2 times (10µs+0s) by Locale::Maketext::Simple::import at line 120, avg 5µs/call | ||||
| 204 | 2 | 3µs | my ($self, %args) = @_; | ||
| 205 | 2 | 2µs | my $style = lc($args{Style}); | ||
| 206 | 2 | 7µs | if ($style eq 'maketext') { | ||
| 207 | return sub { | ||||
| 208 | my $str = shift; | ||||
| 209 | $str =~ s{((?<!~)(?:~~)*)\[_([1-9]\d*|\*)\]} | ||||
| 210 | {$1%$2}g; | ||||
| 211 | $str =~ s{((?<!~)(?:~~)*)\[([A-Za-z#*]\w*),([^\]]+)\]} | ||||
| 212 | {"$1%$2(" . _escape($3) . ')'}eg; | ||||
| 213 | _default_gettext($str, @_); | ||||
| 214 | }; | ||||
| 215 | } | ||||
| 216 | elsif ($style eq 'gettext') { | ||||
| 217 | return \&_default_gettext; | ||||
| 218 | } | ||||
| 219 | else { | ||||
| 220 | die "Unknown Style: $style"; | ||||
| 221 | } | ||||
| 222 | } | ||||
| 223 | |||||
| 224 | sub _default_gettext { | ||||
| 225 | my $str = shift; | ||||
| 226 | $str =~ s{ | ||||
| 227 | my $digit = $2 || shift; | ||||
| 228 | $digit . ( | ||||
| 229 | $1 ? ( | ||||
| 230 | ($1 eq 'tense') ? (($3 eq 'present') ? 'ing' : 'ed') : | ||||
| 231 | ($1 eq 'quant') ? ' ' . (($digit > 1) ? ($4 || "$3s") : $3) : | ||||
| 232 | '' | ||||
| 233 | ) : '' | ||||
| 234 | ); | ||||
| 235 | }egx; | ||||
| 236 | ) # end either | ||||
| 237 | (?: # maybe followed | ||||
| 238 | , # by a comma | ||||
| 239 | ([^),]*) # and a param -- 3 | ||||
| 240 | )? # end maybe | ||||
| 241 | (?: # maybe followed | ||||
| 242 | , # by another comma | ||||
| 243 | ([^),]*) # and a param -- 4 | ||||
| 244 | )? # end maybe | ||||
| 245 | [^)]* # and other ignorable params | ||||
| 246 | \) # closing function call | ||||
| 247 | ) # closing either one of | ||||
| 248 | }{ | ||||
| 249 | |||||
| - - | |||||
| 258 | return $str; | ||||
| 259 | }; | ||||
| 260 | |||||
| 261 | sub _escape { | ||||
| 262 | my $text = shift; | ||||
| 263 | $text =~ s/\b_([1-9]\d*)/%$1/g; | ||||
| 264 | return $text; | ||||
| 265 | } | ||||
| 266 | |||||
| 267 | sub _unescape { | ||||
| 268 | join(',', map { | ||||
| 269 | /\A(\s*)%([1-9]\d*|\*)(\s*)\z/ ? "$1_$2$3" : $_ | ||||
| 270 | } split(/,/, $_[0])); | ||||
| 271 | } | ||||
| 272 | |||||
| 273 | # spent 1.23ms (95µs+1.13) within Locale::Maketext::Simple::auto_path which was called 2 times, avg 614µs/call:
# 2 times (95µs+1.13ms) by Locale::Maketext::Simple::load_loc at line 141, avg 614µs/call | ||||
| 274 | 2 | 800ns | my ($self, $calldir) = @_; | ||
| 275 | 2 | 13µs | 2 | 5µs | $calldir =~ s#::#/#g; # spent 5µs making 2 calls to Locale::Maketext::Simple::CORE:subst, avg 2µs/call |
| 276 | 2 | 2µs | my $path = $INC{$calldir . '.pm'} or return; | ||
| 277 | |||||
| 278 | # Try absolute path name. | ||||
| 279 | 2 | 4µs | if ($^O eq 'MacOS') { | ||
| 280 | (my $malldir = $calldir) =~ tr#/#:#; | ||||
| 281 | $path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:#s; | ||||
| 282 | } else { | ||||
| 283 | 2 | 55µs | 8 | 37µs | $path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/#; # spent 24µs making 2 calls to Locale::Maketext::Simple::CORE:regcomp, avg 12µs/call
# spent 9µs making 2 calls to Locale::Maketext::Simple::CORE:subst, avg 4µs/call
# spent 4µs making 4 calls to Locale::Maketext::Simple::CORE:substcont, avg 1µs/call |
| 284 | } | ||||
| 285 | |||||
| 286 | 2 | 16µs | 2 | 10µs | return $path if -d $path; # spent 10µs making 2 calls to Locale::Maketext::Simple::CORE:ftdir, avg 5µs/call |
| 287 | |||||
| 288 | # If that failed, try relative path with normal @INC searching. | ||||
| 289 | 2 | 1µs | $path = "auto/$calldir/"; | ||
| 290 | 2 | 2µs | foreach my $inc (@INC) { | ||
| 291 | 20 | 1.13ms | 20 | 1.08ms | return "$inc/$path" if -d "$inc/$path"; # spent 1.08ms making 20 calls to Locale::Maketext::Simple::CORE:ftdir, avg 54µs/call |
| 292 | } | ||||
| 293 | |||||
| 294 | 2 | 8µs | return; | ||
| 295 | } | ||||
| 296 | |||||
| 297 | 1 | 3µs | 1; | ||
| 298 | |||||
| 299 | =head1 ACKNOWLEDGMENTS | ||||
| 300 | |||||
| 301 | Thanks to Jos I. Boumans for suggesting this module to be written. | ||||
| 302 | |||||
| 303 | Thanks to Chia-Liang Kao for suggesting C<Path> and C<loc_lang>. | ||||
| 304 | |||||
| 305 | =head1 SEE ALSO | ||||
| 306 | |||||
| 307 | L<Locale::Maketext>, L<Locale::Maketext::Lexicon> | ||||
| 308 | |||||
| 309 | =head1 AUTHORS | ||||
| 310 | |||||
| 311 | Audrey Tang E<lt>cpan@audreyt.orgE<gt> | ||||
| 312 | |||||
| 313 | =head1 COPYRIGHT | ||||
| 314 | |||||
| 315 | Copyright 2003, 2004, 2005, 2006 by Audrey Tang E<lt>cpan@audreyt.orgE<gt>. | ||||
| 316 | |||||
| 317 | This software is released under the MIT license cited below. Additionally, | ||||
| 318 | when this software is distributed with B<Perl Kit, Version 5>, you may also | ||||
| 319 | redistribute it and/or modify it under the same terms as Perl itself. | ||||
| 320 | |||||
| 321 | =head2 The "MIT" License | ||||
| 322 | |||||
| 323 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| 324 | of this software and associated documentation files (the "Software"), to deal | ||||
| 325 | in the Software without restriction, including without limitation the rights | ||||
| 326 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| 327 | copies of the Software, and to permit persons to whom the Software is | ||||
| 328 | furnished to do so, subject to the following conditions: | ||||
| 329 | |||||
| 330 | The above copyright notice and this permission notice shall be included in | ||||
| 331 | all copies or substantial portions of the Software. | ||||
| 332 | |||||
| 333 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||||
| 334 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| 335 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||||
| 336 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| 337 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||||
| 338 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
| 339 | DEALINGS IN THE SOFTWARE. | ||||
| 340 | |||||
| 341 | =cut | ||||
sub Locale::Maketext::Simple::CORE:ftdir; # opcode | |||||
# spent 24µs within Locale::Maketext::Simple::CORE:regcomp which was called 2 times, avg 12µs/call:
# 2 times (24µs+0s) by Locale::Maketext::Simple::auto_path at line 283, avg 12µs/call | |||||
sub Locale::Maketext::Simple::CORE:subst; # opcode | |||||
# spent 4µs within Locale::Maketext::Simple::CORE:substcont which was called 4 times, avg 1µs/call:
# 4 times (4µs+0s) by Locale::Maketext::Simple::auto_path at line 283, avg 1µs/call |