File Coverage

blib/lib/Locale/CA.pm
Criterion Covered Total %
statement 61 65 93.8
branch 23 30 76.6
condition 9 15 60.0
subroutine 9 9 100.0
pod 3 3 100.0
total 105 122 86.0


line stmt bran cond sub pod time code
1             package Locale::CA;
2              
3 6     6   952547 use warnings;
  6         8  
  6         271  
4 6     6   22 use strict;
  6         7  
  6         83  
5 6     6   18 use Carp;
  6         20  
  6         317  
6 6     6   2171 use Data::Section::Simple;
  6         3418  
  6         253  
7 6     6   2366 use I18N::LangTags::Detect;
  6         25267  
  6         3467  
8              
9             =head1 NAME
10              
11             Locale::CA - two letter codes for province identification in Canada and vice versa
12              
13             =head1 VERSION
14              
15             Version 0.10
16              
17             =cut
18              
19             our $VERSION = '0.10';
20              
21             my %_cache;
22              
23             =head1 SYNOPSIS
24              
25             use Locale::CA;
26              
27             my $u = Locale::CA->new();
28              
29             # Returns the French names of the provinces if $LANG starts with 'fr' or
30             # the lang parameter is set to 'fr'
31             print $u->{code2province}{'ON'}, "\n"; # prints ONTARIO
32             print $u->{province2code}{'ONTARIO'}, "\n"; # prints ON
33              
34             my @province = $u->all_province_names();
35             my @code = $u->all_province_codes();
36              
37             =head1 SUBROUTINES/METHODS
38              
39             =head2 new
40              
41             Creates a Locale::CA object.
42              
43             Can be called both as a class method (Locale::CA->new()) and as an object method ($object->new()).
44              
45             =cut
46              
47             sub new {
48 10     10 1 552610 my $proto = shift;
49 10         14 my $class;
50              
51 10 100       34 if(!defined($proto)) {
    50          
    50          
52 1         2 $class = __PACKAGE__;
53             } elsif(ref($proto)) {
54 0         0 $class = ref($proto);
55 9         62 } elsif(eval { $proto->isa(__PACKAGE__) }) {
56 9         15 $class = $proto;
57             } else {
58             # Function-call style with a non-class first arg — treat as argument
59 0         0 unshift @_, $proto;
60 0         0 $class = __PACKAGE__;
61             }
62              
63 10         14 my %params;
64 10 100       33 if(ref($_[0]) eq 'HASH') {
    100          
    50          
65 1         2 %params = %{$_[0]};
  1         3  
66             } elsif(@_ % 2 == 0) {
67 8         13 %params = @_;
68             } elsif(@_ == 1) {
69 1         4 $params{'lang'} = shift;
70             } else {
71 0         0 Carp::croak(__PACKAGE__, ': Invalid arguments passed to new()');
72             }
73              
74 10         13 my $lang;
75 10 100       24 if(defined(my $explicit = $params{'lang'})) {
76 3         8 $lang = lc($explicit);
77 3 100 66     36 Carp::croak("lang can only be one of 'en' or 'fr', given $explicit")
78             unless $lang eq 'en' || $lang eq 'fr';
79             } else {
80 7         16 my $detected = _get_language();
81 7 100 66     27 if(defined($detected) && ($detected eq 'en' || $detected eq 'fr')) {
      66        
82 3         4 $lang = $detected;
83             } else {
84 4         8 $lang = 'en';
85             }
86             }
87              
88 9 100       22 unless(exists $_cache{$lang}) {
89 4         17 my $data = Data::Section::Simple::get_data_section("provinces_$lang");
90 4 50       1032 Carp::croak("Internal error: data section 'provinces_$lang' not found")
91             unless defined $data;
92              
93 4         5 my(%c2p, %p2c);
94 4         22 for(split /\n/, $data) {
95 61 50       113 next unless /\S/;
96 61         91 my($code, $province) = split /:/, $_, 2;
97 61 50 33     164 next unless defined $code && defined $province;
98 61         97 $c2p{$code} = $province;
99 61         125 $p2c{$province} = $code;
100             }
101 4         25 $_cache{$lang} = { code2province => \%c2p, province2code => \%p2c };
102             }
103              
104             my $self = {
105 9         55 code2province => { %{$_cache{$lang}{code2province}} },
106 9         19 province2code => { %{$_cache{$lang}{province2code}} },
  9         61  
107             };
108              
109 9         51 return bless $self, $class;
110             }
111              
112             # https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html
113             # https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html
114             sub _get_language {
115 7     7   22 for my $tag (I18N::LangTags::Detect::detect()) {
116 2 50       425 if ($tag =~ /^([a-z]{2})/i) {
117 2         7 return lc $1;
118             }
119             }
120 5 100 66     751 return 'en' if ($ENV{LANG} && $ENV{LANG} =~ /^C(?:\.|$)/);
121 4         8 return; # undef
122             }
123              
124             =head2 all_province_codes
125              
126             Returns an array (not arrayref) of all province codes in alphabetical form.
127              
128             =cut
129              
130             sub all_province_codes {
131 1     1 1 561 my $self = shift;
132              
133 1         2 return(sort keys %{$self->{code2province}});
  1         11  
134             }
135              
136             =head2 all_province_names
137              
138             Returns an array (not arrayref) of all province names in alphabetical form
139              
140             =cut
141              
142             sub all_province_names {
143 1     1 1 6945 my $self = shift;
144              
145 1         2 return(sort keys %{$self->{province2code}});
  1         11  
146             }
147              
148             =head2 $self->{code2province}
149              
150             This is a hashref which has two-letter province names as the key and the long
151             name as the value.
152              
153             =head2 $self->{province2code}
154              
155             This is a hashref which has the long name as the key and the two-letter
156             province name as the value.
157              
158             =head1 SEE ALSO
159              
160             L
161              
162             =head1 AUTHOR
163              
164             Nigel Horne, C<< >>
165              
166             =head1 BUGS
167              
168             =over 4
169              
170             =item * Province names are returned in upper-case (C) format.
171              
172             =back
173              
174             =head1 SUPPORT
175              
176             You can find documentation for this module with the perldoc command.
177              
178             perldoc Locale::CA
179              
180             You can also look for information at:
181              
182             =over 4
183              
184             =item * RT: CPAN's request tracker
185              
186             L
187              
188             =item * Search CPAN
189              
190             L
191              
192             =back
193              
194             =head1 ACKNOWLEDGEMENTS
195              
196             Based on L - Copyright (c) 2002 - C<< $present >> Terrence Brannon.
197              
198             =head1 LICENSE AND COPYRIGHT
199              
200             Copyright 2012-2026 Nigel Horne.
201              
202             This program is released under the following licence: GPL2
203              
204             =cut
205              
206             1; # End of Locale::CA
207              
208             # Put the one you want to expand in code2province second
209             # so it overwrites the other when it's loaded
210              
211             __DATA__