File Coverage

blib/lib/Locale/Object/Language.pm
Criterion Covered Total %
statement 107 107 100.0
branch 24 32 75.0
condition 3 6 50.0
subroutine 17 17 100.0
pod 6 8 75.0
total 157 170 92.3


line stmt bran cond sub pod time code
1             package Locale::Object::Language;
2              
3 7     7   41 use strict;
  7         12  
  7         173  
4 7     7   31 use warnings;;
  7         11  
  7         150  
5 7     7   31 use Carp;
  7         11  
  7         10455  
6              
7 7     7   46 use Locale::Object;
  7         14  
  7         162  
8 7     7   47 use base qw( Locale::Object );
  7         13  
  7         671  
9              
10 7     7   43 use Locale::Object::Country;
  7         19  
  7         178  
11 7     7   35 use Locale::Object::DB;
  7         14  
  7         6331  
12              
13             our $VERSION = '0.78';
14              
15             my $db = Locale::Object::DB->new();
16              
17             # Initialize the hash where we'll keep our singleton currency objects.
18             my $existing = {};
19              
20             my $class;
21              
22             # Initialize the object.
23             sub init
24             {
25 53     53 0 89 my $self = shift;
26 53         118 my %params = @_;
27              
28             # One parameter is allowed.
29 53 50       124 croak "Error: You must specify a single parameter for initialization."
30             unless scalar(keys %params) == 1;
31              
32             # It's the only key in %params.
33 53         102 my $parameter = (keys %params)[0];
34            
35             # Make a hash of valid parameters.
36 53         109 my %allowed_params = map { $_ => undef }
  159         301  
37             qw( code_alpha2 code_alpha3 name );
38            
39             # Go no further if the specified parameter wasn't one.
40 53 50       133 croak "Error: You can only specify an alpha2 or alpha3 code or language name for initialization." unless exists $allowed_params{$parameter};
41              
42             # Get the value given for the parameter.
43 53         78 my $value = $params{$parameter};
44              
45             # Make sure input matches style of values in the db.
46 53 100 66     244 if ($parameter eq 'name')
    50          
47             {
48 5         15 $value = ucfirst($value);
49             }
50             elsif ($parameter eq 'code_alpha2' or $parameter eq 'code_alpha3')
51             {
52 48         110 $value = lc($value);
53             }
54              
55             # Look in the database for a match.
56 53         165 my $result = $db->lookup(
57             table => 'language',
58             result_column => '*',
59             search_column => $parameter,
60             value => $value
61             );
62              
63 53 50       4416 croak "Error: Unknown $parameter given for initialization: $value" unless $result;
64              
65 53 100       94 if (defined @{$result}[0])
  53         132  
66             {
67             # Get values from our query.
68 52         64 my $code_alpha2 = @{$result}[0]->{'code_alpha2'};
  52         107  
69 52         66 my $code_alpha3 = @{$result}[0]->{'code_alpha3'};
  52         80  
70 52         116 my $name = @{$result}[0]->{'name'};
  52         91  
71            
72             # Check for pre-existing objects. Return it if there is one.
73 52         119 my $enguage = $self->exists($code_alpha3);
74 52 100       223 return $enguage if $enguage;
75            
76             # If not, make a new object.
77 38         94 _make_language($self, $code_alpha2, $code_alpha3, $name);
78            
79             # Register the new object.
80 38         90 $self->register();
81            
82             # Return the object.
83 38         167 $self;
84             }
85             else
86             {
87 1         212 carp "Warning: No result found in language table for '$value' in $parameter.";
88 1         11 return;
89             }
90              
91             }
92              
93             # Check if objects exist.
94             sub exists {
95 52     52 1 70 my $self = shift;
96            
97             # Check existence of a object with the given parameter or with
98             # the code of the current object.
99 52   33     105 my $code_alpha3 = shift || $self->code_alpha3;
100              
101             # Return the singleton object, if it exists.
102 52         100 $existing->{$code_alpha3};
103             }
104              
105             # Register the object in our hash of existing objects.
106             sub register {
107 38     38 0 50 my $self = shift;
108              
109             # Do nothing unless the object exists.
110 38 50       62 my $code_alpha3 = $self->code_alpha3 or return;
111            
112             # Put the current object into the singleton hash.
113 38         88 $existing->{$code_alpha3} = $self;
114             }
115              
116             sub _make_language
117             {
118 38     38   51 my $self = shift;
119 38         85 my @attributes = @_;
120              
121             # The second attribute we get is the alpha3 language code.
122 38         54 my $code = $attributes[1];
123            
124             # The attributes we want to set.
125 38         74 my @attr_names = qw(code_alpha2 code_alpha3 name);
126            
127             # Initialize a loop counter.
128 38         52 my $counter = 0;
129            
130 38         76 foreach my $current_attribute (@attr_names)
131             {
132             # Set the attributes of the entry for this currency code in the singleton hash.
133 114         343 $self->$current_attribute( $attributes[$counter] );
134              
135 114         180 $counter++;
136             }
137              
138             }
139              
140             # Method for retrieving all countries using this language
141             sub countries
142             {
143 9     9 1 16 my $self = shift;
144            
145             # Check for countries attribute. Set it if we don't have it.
146 9 50       33 _set_countries($self) if $self->{_name};
147            
148             # Give an array if requested in array context, otherwise a reference.
149 9 100       24 return @{$self->{_countries}} if wantarray;
  8         64  
150 1         25 return $self->{_countries};
151             }
152              
153             # Private method to set an attribute with a hash of objects for all countries using this currency.
154             sub _set_countries
155             {
156 9     9   15 my $self = shift;
157 9         15 my $code = $self->{_code_alpha3};
158              
159             # Do nothing if the list already exists.
160 9 100       26 return if $existing->{$code}->{'_countries'};
161              
162             # If it doesn't, find all countries using this currency and put them in a hash.
163 6         10 my @countries;
164              
165 6         18 my $result = $db->lookup(
166             table => 'language_mappings',
167             result_column => 'country',
168             search_column => 'language',
169             value => $code
170             );
171            
172             # Create new country objects and put them into an array.
173 6         1219 foreach my $where (@{$result})
  6         15  
174             {
175 247         494 my $country_code = $where->{'country'};
176 247         1042 my $obj = Locale::Object::Country->new( code_alpha2 => $country_code );
177 247         622 push @countries, $obj;
178             }
179            
180             # Set a reference to that array as an attribute.
181 6         89 $self->{'_countries'} = \@countries;
182             }
183              
184             # Get/set attributes.
185              
186             sub name
187             {
188 43     43 1 980 my $self = shift;
189              
190 43 100       83 if (@_)
191             {
192 38         63 $self->{_name} = shift;
193 38         55 return $self;
194             }
195              
196 5         25 $self->{_name};
197             }
198              
199             sub code_alpha2
200             {
201 66     66 1 87 my $self = shift;
202              
203 66 100       130 if (@_)
204             {
205 38         97 $self->{_code_alpha2} = shift;
206 38         65 return $self;
207             }
208            
209 28         77 $self->{_code_alpha2};
210             }
211              
212             sub code_alpha3
213             {
214 223     223 1 256 my $self = shift;
215              
216 223 100       374 if (@_)
217             {
218 38         75 $self->{_code_alpha3} = shift;
219 38         52 return $self;
220             }
221              
222 185         419 $self->{_code_alpha3};
223             }
224              
225             sub official
226             {
227 23     23 1 36 my $self = shift;
228 23         35 my $where = shift;
229 23         40 my $selected = $self->code_alpha3;
230            
231 23 50       93 croak "Error: you can only pass official() a Locale::Object::Country object." unless $where->isa('Locale::Object::Country');
232              
233 23         55 my $country = $where->code_alpha2;
234              
235 23         37 my $count = 0;
236              
237             # For each language used in the country...
238              
239 23         48 my @langs = ($where->languages);
240            
241 23         46 my %used_langs = map { $_->code_alpha3 => $_ } @langs;
  122         168  
242              
243 23 50       61 croak qq{ERROR: Language "$selected" is not used in } . $where->name . '.' unless exists $used_langs{$selected};
244              
245 23         74 my $result = $db->lookup_dual(
246             table => 'language_mappings',
247             result_col => 'official',
248             col_1 => 'country',
249             val_1 => $country,
250             col_2 => 'language',
251             val_2 => $selected
252             );
253              
254 23         2170 return @{$result}[0]->{'official'};
  23         162  
255             }
256              
257             1;
258              
259             __END__
260              
261             =head1 NAME
262              
263             Locale::Object::Language - language information objects
264              
265             =head1 DESCRIPTION
266              
267             C<Locale::Object::Language> allows you to create objects containing information about languages such as their ISO codes, the countries they're used in and so on.
268              
269             =head1 SYNOPSIS
270              
271             use Locale::Object::Language;
272              
273             my $eng = Locale::Object::Language->new( code_alpha3 => 'eng' );
274              
275             my $name = $eng->name;
276             my $code_alpha2 = $eng->code_alpha2;
277             my $code_alpha3 = $eng->code_alpha3;
278            
279             my @countries = $eng->countries;
280              
281             my $gb = Locale::Object::Country->new( code_alpha2 => 'gb' );
282              
283             print $eng->official($gb);
284              
285             =head1 METHODS
286              
287             =head2 C<new()>
288              
289             my $eng = Locale::Object::Language->new( code_alpha3 => 'eng' );
290              
291             The C<new> method creates an object. It takes a single-item hash as an argument - valid options to pass are ISO 3166 values - 'code_alpha2', 'code_alpha3' and 'name'.
292              
293             The objects created are singletons; if you try and create a currency object when one matching your specification already exists, C<new()> will return the original one.
294              
295             =head2 C<name(), code_alpha2(), code_alpha3()>
296              
297             my $name = $country->name;
298            
299             These methods retrieve the values of the attributes in the object whose name they share.
300              
301             =head2 C<countries()>
302              
303             my @countries = $eng->countries;
304              
305             Returns an array (in array context, otherwise a reference) of L<Locale::Object::Country> objects with their ISO 3166 alpha2 codes as keys for all countries using this currency in array context, or a reference in scalar context. The objects have their own attribute methods, so you can do things like this for example:
306              
307             foreach my $place (@countries)
308             {
309             print $place->name, "\n";
310             }
311            
312             Which will list you all the countries that use in that currency. See the documentation for L<Locale::Object::Country> for a listing of country attributes. Note that you can chain methods as well.
313              
314             foreach my $place (@countries)
315             {
316             print $place->continent->name, "\n";
317             }
318              
319             =head2 C<official()>
320              
321             my $gb = Locale::Object::Country->new( code_alpha2 => 'gb' );
322              
323             print $eng->official($gb); # prints 'true'
324              
325             Give this method a L<Locale::Object::Country> object, and it will return a 'true' or 'false' value for whether the country the object represents has the language represented by your C<Locale::Object::Language> object as an official language. See L<Locale::Object::Database> for a note about languages in the database.
326              
327             =head1 OBSOLETE LANGUAGE CODES
328              
329             ISO 639 is not immune from change, and there are three codes that changed in 1995: Hebrew (C<he>, was C<iw>), Indonesian (C<id>, was C<in>) and Yiddish (C<yi>, formerly C<ji>). Because the database maintains a one-to-one mapping, the old codes aren't included; if you need to support them for some reason (apparently Java versions previous to 1.4 use 'iw', for example), you'll have to alias them yourself. Thanks to Robin Szemeti (RSZEMETI) for bringing this to my attention.
330              
331             =head1 KNOWN BUGS
332              
333             The database of language information is not perfect by a long stretch. In particular, numerous comparatively obscure secondary or regional languages that don't have ISO codes, such as in several African countries and India, are missing. (See note in L<Locale::Object::Database> about data sources.) Please send any corrections to the author.
334              
335             =head1 AUTHOR
336              
337             Originally by Earle Martin
338              
339             =head1 COPYRIGHT AND LICENSE
340              
341             Originally by Earle Martin. To the extent possible under law, the author has dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
342              
343             =cut
344