File Coverage

blib/lib/Lingua/String.pm
Criterion Covered Total %
statement 79 87 90.8
branch 36 42 85.7
condition 7 9 77.7
subroutine 11 12 91.6
pod 4 4 100.0
total 137 154 88.9


line stmt bran cond sub pod time code
1             package Lingua::String;
2              
3 4     4   509275 use strict;
  4         38  
  4         117  
4 4     4   21 use warnings;
  4         8  
  4         98  
5 4     4   20 use Carp;
  4         5  
  4         198  
6 4     4   2199 use HTML::Entities;
  4         23998  
  4         445  
7              
8             =head1 NAME
9              
10             Lingua::String - Class to contain a string in many different languages
11              
12             =head1 VERSION
13              
14             Version 0.02
15              
16             =cut
17              
18             our $VERSION = '0.02';
19              
20             use overload (
21             # '==' => \&equal,
22             # '!=' => \¬_equal,
23             '""' => \&as_string,
24 0     0   0 bool => sub { 1 },
25 4         41 fallback => 1 # So that boolean tests don't cause as_string to be called
26 4     4   30 );
  4         6  
27              
28             =head1 SYNOPSIS
29              
30             Hold many strings in one object.
31              
32             use Lingua::String;
33              
34             my $str = Lingua::String->new();
35              
36             $str->fr('Bonjour Tout le Monde');
37             $str->en('Hello, World');
38              
39             $ENV{'LANG'} = 'en_GB';
40             print "$str\n"; # Prints Hello, World
41             $ENV{'LANG'} = 'fr_FR';
42             print "$str\n"; # Prints Bonjour Tout le Monde
43             $LANG{'LANG'} = 'de_DE';
44             print "$str\n"; # Prints nothing
45              
46             =cut
47              
48             =head1 METHODS
49              
50             =head2 new
51              
52             Create a Lingua::String object.
53              
54             use Lingua::String;
55              
56             my $str = Lingua::String->new({ 'en' => 'Here', 'fr' => 'Ici' });
57              
58             =cut
59              
60             sub new {
61 9     9 1 697 my $proto = shift;
62 9   66     49 my $class = ref($proto) || $proto;
63              
64             # Use Lingua::String->new, not Lingua::String::new
65 9 100       25 if(!defined($class)) {
66             # https://github.com/nigelhorne/Lingua-String/issues/1
67 1         37 Carp::carp(__PACKAGE__, ' use ->new() not ::new() to instantiate');
68 1         250 return;
69             }
70              
71 8         16 my %params;
72 8 50       42 if(ref($_[0]) eq 'HASH') {
    100          
73 0         0 %params = %{$_[0]};
  0         0  
74             } elsif(scalar(@_) % 2 == 0) {
75 7         23 %params = @_;
76             } else {
77 1         3 Carp::carp(__PACKAGE__, ': usage: new(%args)');
78 1         531 return;
79             }
80              
81 7 100       20 if(scalar(%params)) {
82 4         19 return bless { strings => \%params }, $class;
83             }
84 3         16 return bless { }, $class;
85             }
86              
87             =head2 set
88              
89             Sets a string in a language.
90              
91             $str->set({ string => 'House', lang => 'en' });
92              
93             Autoload will do this for you as
94              
95             $str->en('House');
96              
97             =cut
98              
99             sub set {
100 3     3 1 498 my $self = shift;
101              
102 3         9 my %params;
103 3 50       18 if(ref($_[0]) eq 'HASH') {
    100          
104 0         0 %params = %{$_[0]};
  0         0  
105             } elsif(scalar(@_) % 2 == 0) {
106 2         7 %params = @_;
107             } else {
108 1         3 $params{'string'} = shift;
109             }
110              
111 3         8 my $lang = $params{'lang'};
112              
113 3 100       10 if(!defined($lang)) {
114 2   66     12 $lang ||= $self->_get_language();
115 2 100       8 if(!defined($lang)) {
116 1         7 Carp::carp(__PACKAGE__, ': usage: set(string => string, lang => $language)');
117 1         358 return;
118             }
119             }
120              
121 2         4 my $string = $params{'string'};
122              
123 2 50       5 if(!defined($string)) {
124 0         0 Carp::carp(__PACKAGE__, ': usage: set(string => string, lang => $language)');
125 0         0 return;
126             }
127              
128 2         5 $self->{'strings'}->{$lang} = $string;
129              
130 2         9 return $self;
131             }
132              
133             # https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html
134             # https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html
135             sub _get_language {
136 14 100   14   48 if($ENV{'LANGUAGE'}) {
137 1 50       7 if($ENV{'LANGUAGE'} =~ /^([a-z]{2})/i) {
138 0         0 return lc($1);
139             }
140             }
141 14         32 foreach my $variable('LC_ALL', 'LC_MESSAGES', 'LANG') {
142 30         62 my $val = $ENV{$variable};
143 30 100       82 next unless(defined($val));
144              
145 12 50       54 if($val =~ /^([a-z]{2})/i) {
146 12         59 return lc($1);
147             }
148             }
149 2         8 return; # undef
150             }
151              
152             =head2 as_string
153              
154             Returns the string in the language requested in the parameter.
155             If that parameter is not given, the system language is used.
156              
157             my $string = Lingua::String->new(en => 'boat', fr => 'bateau');
158             print $string->as_string(), "\n";
159             print $string->as_string('fr'), "\n";
160             print $string->as_string({ lang => 'en' }), "\n";
161              
162             =cut
163              
164             sub as_string {
165 15     15 1 1202 my $self = shift;
166 15         33 my %params;
167              
168 15 100       66 if(ref($_[0]) eq 'HASH') {
    100          
    100          
169 1         2 %params = %{$_[0]};
  1         4  
170             } elsif(scalar(@_) == 0) {
171             # $params{'lang'} = $self->_get_language();
172             } elsif(scalar(@_) % 2 == 0) {
173 6 100       15 if(defined($_[0])) {
174 1         3 %params = @_;
175             }
176             } else {
177 1         2 $params{'lang'} = shift;
178             }
179 15   100     56 my $lang = $params{'lang'} || $self->_get_language();
180              
181 15 100       35 if(!defined($lang)) {
182 1         4 Carp::carp(__PACKAGE__, ': usage: as_string(lang => $language)');
183 1         329 return;
184             }
185 14         102 return $self->{'strings'}->{$lang};
186             }
187              
188             =head2 encode
189              
190             =encoding utf-8
191              
192             Turns the encapsulated strings into HTML entities
193              
194             my $string = Lingua::String->new(en => 'study', fr => 'étude')->encode();
195             print $string->fr(), "\n"; # Prints étude
196              
197             =cut
198              
199             sub encode {
200 2     2 1 700 my $self = shift;
201              
202 2         5 while(my($k, $v) = each(%{$self->{'strings'}})) {
  6         104  
203 4         13 utf8::decode($v);
204 4         10 $self->{'strings'}->{$k} = HTML::Entities::encode_entities($v);
205             }
206 2         12 return $self;
207             }
208              
209             sub AUTOLOAD {
210 13     13   1906 our $AUTOLOAD;
211 13         24 my $key = $AUTOLOAD;
212              
213 13         68 $key =~ s/.*:://;
214              
215 13 100       325 return if($key eq 'DESTROY');
216              
217 6         11 my $self = shift;
218              
219 6 50       15 return if(ref($self) ne __PACKAGE__);
220              
221 6 100       13 if(my $value = shift) {
222 2         28 $self->{'strings'}->{$key} = $value;
223             }
224              
225 6         33 return $self->{'strings'}->{$key};
226             }
227              
228             =head1 AUTHOR
229              
230             Nigel Horne, C<< >>
231              
232             =head1 BUGS
233              
234             There's no decode() (yet) so you'll have to be extra careful to avoid
235             double encoding.
236              
237             =head1 SEE ALSO
238              
239             =head1 SUPPORT
240              
241             You can find documentation for this module with the perldoc command.
242              
243             perldoc Lingua::String
244              
245             You can also look for information at:
246              
247             =over 4
248              
249             =item * MetaCPAN
250              
251             L
252              
253             =item * RT: CPAN's request tracker
254              
255             L
256              
257             =item * CPANTS
258              
259             L
260              
261             =item * CPAN Testers' Matrix
262              
263             L
264              
265             =item * CPAN Ratings
266              
267             L
268              
269             =item * CPAN Testers Dependencies
270              
271             L
272              
273             =back
274              
275             =head1 LICENCE AND COPYRIGHT
276              
277             Copyright 2021 Nigel Horne.
278              
279             This program is released under the following licence: GPL2 for personal use on
280             a single computer.
281             All other users (for example Commercial, Charity, Educational, Government)
282             must apply in writing for a licence for use from Nigel Horne at ``.
283              
284             =cut
285              
286             1;