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   52 use strict;
  7         14  
  7         218  
4 7     7   38 use warnings;;
  7         13  
  7         167  
5 7     7   37 use Carp;
  7         11  
  7         367  
6              
7 7     7   40 use Locale::Object;
  7         15  
  7         166  
8 7     7   34 use base qw( Locale::Object );
  7         15  
  7         804  
9              
10 7     7   53 use Locale::Object::Country;
  7         24  
  7         180  
11 7     7   41 use Locale::Object::DB;
  7         14  
  7         8010  
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 106 my $self = shift;
26 53         126 my %params = @_;
27              
28             # One parameter is allowed.
29 53 50       141 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         119 my $parameter = (keys %params)[0];
34            
35             # Make a hash of valid parameters.
36 53         123 my %allowed_params = map { $_ => undef }
  159         370  
37             qw( code_alpha2 code_alpha3 name );
38            
39             # Go no further if the specified parameter wasn't one.
40 53 50       153 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         111 my $value = $params{$parameter};
44              
45             # Make sure input matches style of values in the db.
46 53 100 66     295 if ($parameter eq 'name')
    50          
47             {
48 5         20 $value = ucfirst($value);
49             }
50             elsif ($parameter eq 'code_alpha2' or $parameter eq 'code_alpha3')
51             {
52 48         99 $value = lc($value);
53             }
54              
55             # Look in the database for a match.
56 53         194 my $result = $db->lookup(
57             table => 'language',
58             result_column => '*',
59             search_column => $parameter,
60             value => $value
61             );
62              
63 53 50       5602 croak "Error: Unknown $parameter given for initialization: $value" unless $result;
64              
65 53 100       100 if (defined @{$result}[0])
  53         165  
66             {
67             # Get values from our query.
68 52         79 my $code_alpha2 = @{$result}[0]->{'code_alpha2'};
  52         122  
69 52         87 my $code_alpha3 = @{$result}[0]->{'code_alpha3'};
  52         93  
70 52         132 my $name = @{$result}[0]->{'name'};
  52         94  
71            
72             # Check for pre-existing objects. Return it if there is one.
73 52         130 my $enguage = $self->exists($code_alpha3);
74 52 100       262 return $enguage if $enguage;
75            
76             # If not, make a new object.
77 38         108 _make_language($self, $code_alpha2, $code_alpha3, $name);
78            
79             # Register the new object.
80 38         103 $self->register();
81            
82             # Return the object.
83 38         204 $self;
84             }
85             else
86             {
87 1         278 carp "Warning: No result found in language table for '$value' in $parameter.";
88 1         14 return;
89             }
90              
91             }
92              
93             # Check if objects exist.
94             sub exists {
95 52     52 1 90 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     128 my $code_alpha3 = shift || $self->code_alpha3;
100              
101             # Return the singleton object, if it exists.
102 52         116 $existing->{$code_alpha3};
103             }
104              
105             # Register the object in our hash of existing objects.
106             sub register {
107 38     38 0 59 my $self = shift;
108              
109             # Do nothing unless the object exists.
110 38 50       75 my $code_alpha3 = $self->code_alpha3 or return;
111            
112             # Put the current object into the singleton hash.
113 38         119 $existing->{$code_alpha3} = $self;
114             }
115              
116             sub _make_language
117             {
118 38     38   63 my $self = shift;
119 38         108 my @attributes = @_;
120              
121             # The second attribute we get is the alpha3 language code.
122 38         71 my $code = $attributes[1];
123            
124             # The attributes we want to set.
125 38         84 my @attr_names = qw(code_alpha2 code_alpha3 name);
126            
127             # Initialize a loop counter.
128 38         57 my $counter = 0;
129            
130 38         93 foreach my $current_attribute (@attr_names)
131             {
132             # Set the attributes of the entry for this currency code in the singleton hash.
133 114         357 $self->$current_attribute( $attributes[$counter] );
134              
135 114         206 $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       41 _set_countries($self) if $self->{_name};
147            
148             # Give an array if requested in array context, otherwise a reference.
149 9 100       32 return @{$self->{_countries}} if wantarray;
  8         75  
150 1         41 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   16 my $self = shift;
157 9         18 my $code = $self->{_code_alpha3};
158              
159             # Do nothing if the list already exists.
160 9 100       38 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         12 my @countries;
164              
165 6         27 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         1713 foreach my $where (@{$result})
  6         22  
174             {
175 256         906 my $country_code = $where->{'country'};
176 256         1581 my $obj = Locale::Object::Country->new( code_alpha2 => $country_code );
177 256         1079 push @countries, $obj;
178             }
179            
180             # Set a reference to that array as an attribute.
181 6         103 $self->{'_countries'} = \@countries;
182             }
183              
184             # Get/set attributes.
185              
186             sub name
187             {
188 43     43 1 829 my $self = shift;
189              
190 43 100       102 if (@_)
191             {
192 38         73 $self->{_name} = shift;
193 38         58 return $self;
194             }
195              
196 5         29 $self->{_name};
197             }
198              
199             sub code_alpha2
200             {
201 66     66 1 97 my $self = shift;
202              
203 66 100       141 if (@_)
204             {
205 38         114 $self->{_code_alpha2} = shift;
206 38         79 return $self;
207             }
208            
209 28         101 $self->{_code_alpha2};
210             }
211              
212             sub code_alpha3
213             {
214 223     223 1 311 my $self = shift;
215              
216 223 100       385 if (@_)
217             {
218 38         73 $self->{_code_alpha3} = shift;
219 38         61 return $self;
220             }
221              
222 185         546 $self->{_code_alpha3};
223             }
224              
225             sub official
226             {
227 23     23 1 43 my $self = shift;
228 23         39 my $where = shift;
229 23         52 my $selected = $self->code_alpha3;
230            
231 23 50       112 croak "Error: you can only pass official() a Locale::Object::Country object." unless $where->isa('Locale::Object::Country');
232              
233 23         69 my $country = $where->code_alpha2;
234              
235 23         43 my $count = 0;
236              
237             # For each language used in the country...
238              
239 23         60 my @langs = ($where->languages);
240            
241 23         55 my %used_langs = map { $_->code_alpha3 => $_ } @langs;
  122         191  
242              
243 23 50       77 croak qq{ERROR: Language "$selected" is not used in } . $where->name . '.' unless exists $used_langs{$selected};
244              
245 23         78 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         2609 return @{$result}[0]->{'official'};
  23         192  
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