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 | load_loc | Locale::Maketext::Simple::
3 | 3 | 3 | 53µs | 289µs | import | Locale::Maketext::Simple::
3 | 1 | 1 | 9µs | 9µs | default_loc | Locale::Maketext::Simple::
1 | 1 | 1 | 7µs | 8µs | BEGIN@4 | Locale::Maketext::Simple::
1 | 1 | 1 | 6µs | 6µs | BEGIN@5 | Locale::Maketext::Simple::
1 | 1 | 1 | 4µs | 8µs | BEGIN@122 | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | __ANON__[:124] | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | __ANON__[:176] | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | __ANON__[:197] | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | __ANON__[:205] | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | __ANON__[:219] | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | _default_gettext | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | _escape | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | _unescape | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | auto_path | Locale::Maketext::Simple::
0 | 0 | 0 | 0s | 0s | reload_loc | Locale::Maketext::Simple::
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 |