File Coverage

lib/i18n.pm
Criterion Covered Total %
statement 105 118 88.9
branch 18 34 52.9
condition 4 9 44.4
subroutine 20 23 86.9
pod n/a
total 147 184 79.8


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