File Coverage

lib/i18n.pm
Criterion Covered Total %
statement 115 118 97.4
branch 27 34 79.4
condition 5 9 55.5
subroutine 22 23 95.6
pod n/a
total 169 184 91.8


line stmt bran cond sub pod time code
1             package i18n;
2             $i18n::VERSION = '0.12';
3              
4 1     1   24832 use 5.006;
  1         3  
5 1     1   4 use strict;
  1         1  
  1         23  
6 1     1   5 use constant DATA => 0;
  1         1  
  1         78  
7 1     1   4 use constant LINE => 1;
  1         1  
  1         40  
8 1     1   3 use constant PACKAGE => 2;
  1         1  
  1         43  
9 1     1   4 use constant NEGATED => 3;
  1         2  
  1         46  
10 1     1   4 use warnings::register;
  1         1  
  1         166  
11             use overload (
12 1         35 '~' => \&_negate,
13             '.' => \&_concat,
14             '""' => \&_stringify,
15             fallback => 1,
16 1     1   13495 );
  1         2131  
17              
18             sub import {
19 1     1   28 my $class = shift;
20 1         3 my $caller = caller;
21              
22 1         17 local $@;
23 1 50       4 eval { require Locale::Maketext::Simple; 1 } or return;
  1         1402  
  1         5694  
24              
25             overload::constant(
26             q => sub {
27 49     49   100 shift;
28 49         38 pop;
29 49         753 bless(
30             [
31             \@_, # DATA
32             ( caller(1) )[2], # LINE
33             $caller, # PACKAGE
34             ],
35             $class
36             );
37             },
38 1         16 );
39              
40             {
41 1     1   573 no strict 'refs';
  1         2  
  1         166  
  1         174  
42 1     1   43 no warnings 'redefine';
  1         4  
  1         3813  
43              
44 1         3 delete ${"$class\::"}{loc};
  1         124  
45 1         3 delete ${"$class\::"}{loc_lang};
  1         10  
46              
47 1 50       7 unshift @_, 'Path' if @_ % 2;
48 1         11 Locale::Maketext::Simple->import(@_);
49              
50 1         97390 *{"$caller\::loc"} = $class->can('loc');
  1         8  
51 1         6 *{"$caller\::loc_lang"} = $class->can('loc_lang');
  1         5  
52              
53 1         3 *{"$class\::loc"} = \&_loc;
  1         5  
54 1         3 *{"$class\::loc_lang"} = \&_loc_lang;
  1         4  
55             }
56              
57 1         4 @_ = ( warnings => $class );
58 1         76 goto &warnings::import;
59             }
60              
61             sub unimport {
62 1     1   8 my $class = shift;
63 1         11 overload::remove_constant('q');
64              
65 1         18 @_ = ( warnings => $class );
66 1         122 goto &warnings::unimport;
67             }
68              
69             sub loc { goto \&_loc }
70             sub loc_lang { goto \&_loc_lang }
71              
72             sub _loc {
73 1     1   2 my $class = shift;
74 1 50       7 return $_[0] unless UNIVERSAL::can( $_[0], '_negate' );
75 1         3 goto &_do_loc;
76             }
77              
78             sub _loc_lang {
79 3     3   980 my $class = shift;
80 3         39 my $caller = caller;
81 3 50       30 my $loc_lang = $caller->can('loc_lang') or return;
82 3         20 goto &$loc_lang;
83             }
84              
85             sub _negate {
86 22     22   507 my $class = ref $_[0];
87              
88 22 100       1274 return ~_stringify( $_[0] ) unless warnings::enabled($class);
89              
90 21 100       77 goto &_do_loc if $_[0][NEGATED];
91              
92             bless(
93             [
94 11         13 [ @{ $_[0][DATA] } ], # DATA
  11         84  
95             $_[0][LINE], # LINE
96             $_[0][PACKAGE], # PACKAGE
97             1, # NEGATED
98             ],
99             $class
100             );
101             }
102              
103             sub _concat {
104 13     13   4865 my $class = ref $_[0];
105 13         28 my $pkg = $_[0][PACKAGE];
106              
107 13 100       38 @_ = reverse(@_) if pop;
108 13 100       845 return join( '', @_ ) unless warnings::enabled($class);
109              
110 12         30 my $line = (caller)[2];
111 12         19 my ( $seen, @data );
112              
113 12         27 foreach (@_) {
114 24 100 66     156 ( push( @data, bless( \\$_, "$class\::var" ) ), next )
115             unless ref($_)
116             and UNIVERSAL::isa( $_, $class );
117 21         22 $seen++;
118              
119 21 100 66     115 ( push( @data, bless( \\$_, "$class\::var" ) ), next )
120             unless $_->[LINE] == $line and !$_->[NEGATED];
121 14         14 $seen++;
122              
123 14         17 $pkg = $_->[PACKAGE];
124 14         13 push @data, @{ $_->[DATA] };
  14         45  
125             }
126              
127 12 50       25 return join( '', @data ) if $seen < 2;
128              
129 12         68 return bless(
130             [
131             \@data, # DATA
132             $line, # LINE
133             $pkg, # PACKAGE
134             ],
135             $class
136             );
137             }
138              
139             sub _stringify {
140             ( $_[0][NEGATED] )
141 1 50       12 ? ~join( '', map { ( ref $_ ) ? "$$$_" : "$_" } @{ $_[0][DATA] } )
  1         4  
142 44 100   44   4869 : join( '', map { ( ref $_ ) ? "$$$_" : "$_" } @{ $_[0][DATA] } );
  44 100       2539  
  43         106  
143             }
144              
145             sub _do_loc {
146 11     11   17 my $class = ref $_[0];
147 11         16 my $pkg = $_[0][PACKAGE];
148              
149 11 50 33     109 ( $pkg eq caller ) and my $loc = $pkg->can('loc')
150             or return ~"$_[0]";
151              
152 11         14 my @vars;
153             my $format = join(
154             '',
155             map {
156             UNIVERSAL::isa( $_, "$class\::var" )
157 9         19 ? do { push( @vars, $$$_ ); "[_" . @vars . "]" }
  9         40  
158 22 100       98 : do { my $str = $_; $str =~ s/(?=[\[\]~])/~/g; $str };
  13         19  
  13         30  
  13         38  
159 11         14 } @{ $_[0][DATA] }
  11         35  
160             );
161              
162             # Defeat constant folding
163 11 100       96 return bless( [ $loc => $format ], 'i18n::string' ) if !@vars;
164              
165 8         24 @_ = ( $format, @vars );
166 8         35 goto &$loc;
167             }
168              
169             package
170             i18n::string;
171              
172             use overload (
173 1         21 '""' => \&_stringify,
174             '0+' => \&_stringify,
175             fallback => 1,
176 1     1   12 );
  1         2  
177              
178             sub _stringify {
179 4     4   993 $_[0][0]->( $_[0][1] );
180             }
181              
182             package
183             i18n::var;
184              
185             use overload (
186 1         6 '""' => \&_stringify,
187             '0+' => \&_stringify,
188             fallback => 1,
189 1     1   344 );
  1         8  
190              
191 0     0     sub _stringify { ${ ${ $_[0] } } }
  0            
  0            
192              
193             1;
194              
195             __END__