File Coverage

lib/i18n.pm
Criterion Covered Total %
statement 115 118 97.4
branch 27 34 79.4
condition 4 6 66.6
subroutine 22 23 95.6
pod n/a
total 168 181 92.8


line stmt bran cond sub pod time code
1             package i18n;
2             $i18n::VERSION = '0.13';
3              
4 1     1   69833 use 5.006;
  1         4  
5 1     1   5 use strict;
  1         2  
  1         22  
6 1     1   5 use constant DATA => 0;
  1         1  
  1         93  
7 1     1   6 use constant LINE => 1;
  1         2  
  1         53  
8 1     1   6 use constant PACKAGE => 2;
  1         2  
  1         61  
9 1     1   7 use constant NEGATED => 3;
  1         1  
  1         50  
10 1     1   7 use warnings::register;
  1         3  
  1         185  
11             use overload (
12 1         7 '~' => \&_negate,
13             '.' => \&_concat,
14             '""' => \&_stringify,
15             fallback => 1,
16 1     1   1221 );
  1         944  
17              
18             sub import {
19 1     1   7 my $class = shift;
20 1         3 my $caller = caller;
21              
22 1         1 local $@;
23 1 50       2 eval { require Locale::Maketext::Simple; 1 } or return;
  1         522  
  1         1632  
24              
25             overload::constant(
26             q => sub {
27 52     52   123 shift;
28 52         57 pop;
29 52         617 bless(
30             [
31             \@_, # DATA
32             ( caller(1) )[2], # LINE
33             $caller, # PACKAGE
34             ],
35             $class
36             );
37             },
38 1         9 );
39              
40             {
41 1     1   189 no strict 'refs';
  1         2  
  1         45  
  1         24  
42 1     1   26 no warnings 'redefine';
  1         3  
  1         1015  
43              
44 1         2 delete ${"$class\::"}{loc};
  1         9  
45 1         1 delete ${"$class\::"}{loc_lang};
  1         6  
46              
47 1 50       10 unshift @_, 'Path' if @_ % 2;
48 1         7 Locale::Maketext::Simple->import(@_);
49              
50 1         31680 *{"$caller\::loc"} = $class->can('loc');
  1         5  
51 1         5 *{"$caller\::loc_lang"} = $class->can('loc_lang');
  1         3  
52              
53 1         3 *{"$class\::loc"} = \&_loc;
  1         4  
54 1         2 *{"$class\::loc_lang"} = \&_loc_lang;
  1         3  
55             }
56              
57 1         3 @_ = ( warnings => $class );
58 1         56 goto &warnings::import;
59             }
60              
61             sub unimport {
62 1     1   9 my $class = shift;
63 1         4 overload::remove_constant('q');
64              
65 1         14 @_ = ( warnings => $class );
66 1         92 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   706 my $class = shift;
80 3         7 my $caller = caller;
81 3 50       19 my $loc_lang = $caller->can('loc_lang') or return;
82 3         15 goto &$loc_lang;
83             }
84              
85             sub _negate {
86 22     22   355 my $class = ref $_[0];
87              
88 22 100       806 return ~_stringify( $_[0] ) unless warnings::enabled($class);
89              
90 21 100       76 goto &_do_loc if $_[0][NEGATED];
91              
92             bless(
93             [
94 11         329 [ @{ $_[0][DATA] } ], # DATA
  11         64  
95             $_[0][LINE], # LINE
96             $_[0][PACKAGE], # PACKAGE
97             1, # NEGATED
98             ],
99             $class
100             );
101             }
102              
103             sub _concat {
104 13     13   3741 my $class = ref $_[0];
105 13         22 my $pkg = $_[0][PACKAGE];
106              
107 13 100       30 @_ = reverse(@_) if pop;
108 13 100       580 return join( '', @_ ) unless warnings::enabled($class);
109              
110 12         38 my $line = (caller)[2];
111 12         23 my ( $seen, @data );
112              
113 12         21 foreach (@_) {
114 24 100 66     118 ( push( @data, bless( \\$_, "$class\::var" ) ), next )
115             unless ref($_)
116             and UNIVERSAL::isa( $_, $class );
117 21         29 $seen++;
118              
119 21 100 66     89 ( push( @data, bless( \\$_, "$class\::var" ) ), next )
120             unless $_->[LINE] == $line and !$_->[NEGATED];
121 14         20 $seen++;
122              
123 14         20 $pkg = $_->[PACKAGE];
124 14         19 push @data, @{ $_->[DATA] };
  14         34  
125             }
126              
127 12 50       23 return join( '', @data ) if $seen < 2;
128              
129 12         55 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       9 ? ~join( '', map { ( ref $_ ) ? "$$$_" : "$_" } @{ $_[0][DATA] } )
  1         4  
142 47 100   47   3714 : join( '', map { ( ref $_ ) ? "$$$_" : "$_" } @{ $_[0][DATA] } );
  47 100       2004  
  46         92  
143             }
144              
145             sub _do_loc {
146 11     11   18 my $class = ref $_[0];
147 11         15 my $pkg = $_[0][PACKAGE];
148              
149 11 50       55 my $loc = $pkg->can('loc')
150             or return ~"$_[0]";
151              
152 11         17 my @vars;
153             my $format = join(
154             '',
155             map {
156             UNIVERSAL::isa( $_, "$class\::var" )
157 9         14 ? do { push( @vars, $$$_ ); "[_" . @vars . "]" }
  9         48  
158 22 100       82 : do { my $str = $_; $str =~ s/(?=[\[\]~])/~/g; $str };
  13         19  
  13         34  
  13         30  
159 11         24 } @{ $_[0][DATA] }
  11         26  
160             );
161              
162             # Defeat constant folding
163 11 100       69 return bless( [ $loc => $format ], 'i18n::string' ) if !@vars;
164              
165 8         19 @_ = ( $format, @vars );
166 8         29 goto &$loc;
167             }
168              
169             package
170             i18n::string;
171              
172             use overload (
173 1         5 '""' => \&_stringify,
174             '0+' => \&_stringify,
175             fallback => 1,
176 1     1   15 );
  1         3  
177              
178             sub _stringify {
179 5     5   1610 $_[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   140 );
  1         2  
190              
191 0     0     sub _stringify { ${ ${ $_[0] } } }
  0            
  0            
192              
193             1;
194              
195             __END__