| Filename | /usr/share/perl5/DateTime/Locale.pm |
| Statements | Executed 14999 statements in 80.2ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 466 | 1 | 1 | 25.8ms | 54.0ms | DateTime::Locale::_register |
| 1 | 1 | 1 | 10.6ms | 10.7ms | DateTime::Locale::BEGIN@11 |
| 1 | 1 | 1 | 5.41ms | 23.7ms | DateTime::Locale::add_aliases |
| 422 | 1 | 1 | 4.92ms | 18.3ms | DateTime::Locale::_registered_id |
| 1 | 1 | 1 | 4.22ms | 4.71ms | DateTime::Locale::BEGIN@10 |
| 1 | 1 | 1 | 3.99ms | 58.0ms | DateTime::Locale::register |
| 466 | 1 | 1 | 828µs | 828µs | DateTime::Locale::CORE:match (opcode) |
| 1 | 1 | 1 | 630µs | 5.57ms | DateTime::Locale::_load_class_from_id |
| 1 | 1 | 1 | 92µs | 82.1ms | DateTime::Locale::BEGIN@140 |
| 1 | 1 | 1 | 44µs | 44µs | DateTime::Locale::BEGIN@6 |
| 1 | 1 | 1 | 31µs | 5.64ms | DateTime::Locale::load |
| 1 | 1 | 1 | 19µs | 435µs | DateTime::Locale::BEGIN@12 |
| 1 | 1 | 1 | 16µs | 20µs | DateTime::Locale::BEGIN@3 |
| 1 | 1 | 1 | 10µs | 22µs | DateTime::Locale::BEGIN@4 |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::_guess_id |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::_parse_id |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::ids |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::names |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::native_names |
| 0 | 0 | 0 | 0s | 0s | DateTime::Locale::remove_alias |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package DateTime::Locale; | ||||
| 2 | |||||
| 3 | 3 | 27µs | 2 | 25µs | # spent 20µs (16+4) within DateTime::Locale::BEGIN@3 which was called:
# once (16µs+4µs) by DateTime::BEGIN@40 at line 3 # spent 20µs making 1 call to DateTime::Locale::BEGIN@3
# spent 4µs making 1 call to strict::import |
| 4 | 3 | 25µs | 2 | 35µs | # spent 22µs (10+13) within DateTime::Locale::BEGIN@4 which was called:
# once (10µs+13µs) by DateTime::BEGIN@40 at line 4 # spent 22µs making 1 call to DateTime::Locale::BEGIN@4
# spent 13µs making 1 call to warnings::import |
| 5 | |||||
| 6 | 3 | 73µs | 1 | 44µs | # spent 44µs within DateTime::Locale::BEGIN@6 which was called:
# once (44µs+0s) by DateTime::BEGIN@40 at line 6 # spent 44µs making 1 call to DateTime::Locale::BEGIN@6 |
| 7 | |||||
| 8 | # Loading this here isn't necessary, but it makes it easier to catch | ||||
| 9 | # syntax errors when testing. | ||||
| 10 | 3 | 161µs | 1 | 4.71ms | # spent 4.71ms (4.22+487µs) within DateTime::Locale::BEGIN@10 which was called:
# once (4.22ms+487µs) by DateTime::BEGIN@40 at line 10 # spent 4.71ms making 1 call to DateTime::Locale::BEGIN@10 |
| 11 | 3 | 203µs | 1 | 10.7ms | # spent 10.7ms (10.6+79µs) within DateTime::Locale::BEGIN@11 which was called:
# once (10.6ms+79µs) by DateTime::BEGIN@40 at line 11 # spent 10.7ms making 1 call to DateTime::Locale::BEGIN@11 |
| 12 | 3 | 624µs | 2 | 851µs | # spent 435µs (19+416) within DateTime::Locale::BEGIN@12 which was called:
# once (19µs+416µs) by DateTime::BEGIN@40 at line 12 # spent 435µs making 1 call to DateTime::Locale::BEGIN@12
# spent 416µs making 1 call to Exporter::import |
| 13 | |||||
| 14 | 1 | 900ns | our $VERSION = '0.45'; | ||
| 15 | |||||
| 16 | 1 | 400ns | my %Class; | ||
| 17 | 1 | 200ns | my %DataForID; | ||
| 18 | 1 | 200ns | my %NameToID; | ||
| 19 | 1 | 100ns | my %NativeNameToID; | ||
| 20 | 1 | 200ns | my %AliasToID; | ||
| 21 | 1 | 200ns | my %IDToExtra; | ||
| 22 | |||||
| 23 | 1 | 200ns | my %LoadCache; | ||
| 24 | |||||
| 25 | # spent 58.0ms (3.99+54.0) within DateTime::Locale::register which was called:
# once (3.99ms+54.0ms) by DateTime::Locale::BEGIN@140 at line 141 | ||||
| 26 | 1 | 1µs | my $class = shift; | ||
| 27 | |||||
| 28 | 1 | 1µs | %LoadCache = (); | ||
| 29 | |||||
| 30 | 1 | 3.28ms | 466 | 54.0ms | if ( ref $_[0] ) { # spent 54.0ms making 466 calls to DateTime::Locale::_register, avg 116µs/call |
| 31 | $class->_register(%$_) foreach @_; | ||||
| 32 | } | ||||
| 33 | else { | ||||
| 34 | $class->_register(@_); | ||||
| 35 | } | ||||
| 36 | } | ||||
| 37 | |||||
| 38 | # spent 54.0ms (25.8+28.2) within DateTime::Locale::_register which was called 466 times, avg 116µs/call:
# 466 times (25.8ms+28.2ms) by DateTime::Locale::register at line 30, avg 116µs/call | ||||
| 39 | 466 | 359µs | my $class = shift; | ||
| 40 | |||||
| 41 | 466 | 37.3ms | 466 | 27.4ms | my %p = validate( # spent 27.4ms making 466 calls to Params::Validate::_validate, avg 59µs/call # spent 2.08ms executing statements in 466 string evals (merged) |
| 42 | @_, { | ||||
| 43 | id => { type => SCALAR }, | ||||
| 44 | |||||
| 45 | en_language => { type => SCALAR }, | ||||
| 46 | en_script => { type => SCALAR, optional => 1 }, | ||||
| 47 | en_territory => { type => SCALAR, optional => 1 }, | ||||
| 48 | en_variant => { type => SCALAR, optional => 1 }, | ||||
| 49 | |||||
| 50 | native_language => { type => SCALAR, optional => 1 }, | ||||
| 51 | native_script => { type => SCALAR, optional => 1 }, | ||||
| 52 | native_territory => { type => SCALAR, optional => 1 }, | ||||
| 53 | native_variant => { type => SCALAR, optional => 1 }, | ||||
| 54 | |||||
| 55 | class => { type => SCALAR, optional => 1 }, | ||||
| 56 | replace => { type => SCALAR, default => 0 }, | ||||
| 57 | } | ||||
| 58 | ); | ||||
| 59 | |||||
| 60 | 466 | 471µs | my $id = $p{id}; | ||
| 61 | |||||
| 62 | 466 | 2.16ms | 466 | 828µs | die "'\@' or '=' are not allowed in locale ids" # spent 828µs making 466 calls to DateTime::Locale::CORE:match, avg 2µs/call |
| 63 | if $id =~ /[\@=]/; | ||||
| 64 | |||||
| 65 | 466 | 798µs | die | ||
| 66 | "You cannot replace an existing locale ('$id') unless you also specify the 'replace' parameter as true\n" | ||||
| 67 | if !delete $p{replace} && exists $DataForID{$id}; | ||||
| 68 | |||||
| 69 | 466 | 307µs | $p{native_language} = $p{en_language} | ||
| 70 | unless exists $p{native_language}; | ||||
| 71 | |||||
| 72 | 466 | 143µs | my @en_pieces; | ||
| 73 | 466 | 99µs | my @native_pieces; | ||
| 74 | 466 | 750µs | foreach my $p (qw( language script territory variant )) { | ||
| 75 | 1864 | 1.80ms | push @en_pieces, $p{"en_$p"} if exists $p{"en_$p"}; | ||
| 76 | 1864 | 2.20ms | push @native_pieces, $p{"native_$p"} if exists $p{"native_$p"}; | ||
| 77 | } | ||||
| 78 | |||||
| 79 | 466 | 800µs | $p{en_complete_name} = join ' ', @en_pieces; | ||
| 80 | 466 | 690µs | $p{native_complete_name} = join ' ', @native_pieces; | ||
| 81 | |||||
| 82 | 466 | 699µs | $DataForID{$id} = \%p; | ||
| 83 | |||||
| 84 | 466 | 752µs | $NameToID{ $p{en_complete_name} } = $id; | ||
| 85 | 466 | 653µs | $NativeNameToID{ $p{native_complete_name} } = $id; | ||
| 86 | |||||
| 87 | 466 | 2.66ms | $Class{$id} = $p{class} if defined exists $p{class}; | ||
| 88 | } | ||||
| 89 | |||||
| 90 | # spent 18.3ms (4.92+13.4) within DateTime::Locale::_registered_id which was called 422 times, avg 43µs/call:
# 422 times (4.92ms+13.4ms) by DateTime::Locale::add_aliases at line 108, avg 43µs/call | ||||
| 91 | 422 | 236µs | shift; | ||
| 92 | 422 | 14.8ms | 422 | 13.4ms | my ($id) = validate_pos( @_, { type => SCALAR } ); # spent 13.4ms making 422 calls to Params::Validate::_validate_pos, avg 32µs/call # spent 1.66ms executing statements in 422 string evals (merged) |
| 93 | |||||
| 94 | 422 | 342µs | return 1 if $AliasToID{$id}; | ||
| 95 | 422 | 1.71ms | return 1 if $DataForID{$id}; | ||
| 96 | |||||
| 97 | return 0; | ||||
| 98 | } | ||||
| 99 | |||||
| 100 | # spent 23.7ms (5.41+18.3) within DateTime::Locale::add_aliases which was called:
# once (5.41ms+18.3ms) by DateTime::Locale::BEGIN@140 at line 142 | ||||
| 101 | 1 | 700ns | shift; | ||
| 102 | |||||
| 103 | 1 | 1µs | %LoadCache = (); | ||
| 104 | |||||
| 105 | 1 | 226µs | my $aliases = ref $_[0] ? $_[0] : {@_}; | ||
| 106 | |||||
| 107 | 1 | 1.12ms | while ( my ( $alias, $id ) = each %$aliases ) { | ||
| 108 | 422 | 1.06ms | 422 | 18.3ms | die # spent 18.3ms making 422 calls to DateTime::Locale::_registered_id, avg 43µs/call |
| 109 | "Unregistered locale '$id' cannot be used as an alias target for $alias" | ||||
| 110 | unless __PACKAGE__->_registered_id($id); | ||||
| 111 | |||||
| 112 | 422 | 335µs | die "Can't alias an id to itself" | ||
| 113 | if $alias eq $id; | ||||
| 114 | |||||
| 115 | # check for overwrite? | ||||
| 116 | |||||
| 117 | 422 | 786µs | my %seen = ( $alias => 1, $id => 1 ); | ||
| 118 | 422 | 186µs | my $copy = $id; | ||
| 119 | 422 | 518µs | while ( $copy = $AliasToID{$copy} ) { | ||
| 120 | die "Creating an alias from $alias to $id would create a loop.\n" | ||||
| 121 | if $seen{$copy}; | ||||
| 122 | |||||
| 123 | $seen{$copy} = 1; | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | 422 | 714µs | $AliasToID{$alias} = $id; | ||
| 127 | } | ||||
| 128 | } | ||||
| 129 | |||||
| 130 | sub remove_alias { | ||||
| 131 | shift; | ||||
| 132 | |||||
| 133 | %LoadCache = (); | ||||
| 134 | |||||
| 135 | my ($alias) = validate_pos( @_, { type => SCALAR } ); | ||||
| 136 | |||||
| 137 | return delete $AliasToID{$alias}; | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | # spent 82.1ms (92µs+82.0) within DateTime::Locale::BEGIN@140 which was called:
# once (92µs+82.0ms) by DateTime::BEGIN@40 at line 143 | ||||
| 141 | 1 | 56µs | 2 | 58.0ms | __PACKAGE__->register( DateTime::Locale::Catalog->Locales() ); # spent 58.0ms making 1 call to DateTime::Locale::register
# spent 31µs making 1 call to DateTime::Locale::Catalog::Locales |
| 142 | 1 | 21µs | 2 | 23.9ms | __PACKAGE__->add_aliases( DateTime::Locale::Catalog->Aliases() ); # spent 23.7ms making 1 call to DateTime::Locale::add_aliases
# spent 227µs making 1 call to DateTime::Locale::Catalog::Aliases |
| 143 | 1 | 778µs | 1 | 82.1ms | } # spent 82.1ms making 1 call to DateTime::Locale::BEGIN@140 |
| 144 | |||||
| 145 | sub ids { wantarray ? keys %DataForID : [ keys %DataForID ] } | ||||
| 146 | sub names { wantarray ? keys %NameToID : [ keys %NameToID ] } | ||||
| 147 | |||||
| 148 | sub native_names { | ||||
| 149 | wantarray ? keys %NativeNameToID : [ keys %NativeNameToID ]; | ||||
| 150 | } | ||||
| 151 | |||||
| 152 | # These are hardcoded for backwards comaptibility with the | ||||
| 153 | # DateTime::Language code. | ||||
| 154 | 1 | 15µs | my %OldAliases = ( | ||
| 155 | 'Afar' => 'aa', | ||||
| 156 | 'Amharic' => 'am_ET', | ||||
| 157 | 'Austrian' => 'de_AT', | ||||
| 158 | 'Brazilian' => 'pt_BR', | ||||
| 159 | 'Czech' => 'cs_CZ', | ||||
| 160 | 'Danish' => 'da_DK', | ||||
| 161 | 'Dutch' => 'nl_NL', | ||||
| 162 | 'English' => 'en_US', | ||||
| 163 | 'French' => 'fr_FR', | ||||
| 164 | |||||
| 165 | # 'Gedeo' => undef, # XXX | ||||
| 166 | 'German' => 'de_DE', | ||||
| 167 | 'Italian' => 'it_IT', | ||||
| 168 | 'Norwegian' => 'no_NO', | ||||
| 169 | 'Oromo' => 'om_ET', # Maybe om_KE or plain om ? | ||||
| 170 | 'Portugese' => 'pt_PT', | ||||
| 171 | 'Sidama' => 'sid', | ||||
| 172 | 'Somali' => 'so_SO', | ||||
| 173 | 'Spanish' => 'es_ES', | ||||
| 174 | 'Swedish' => 'sv_SE', | ||||
| 175 | 'Tigre' => 'tig', | ||||
| 176 | 'TigrinyaEthiopian' => 'ti_ET', | ||||
| 177 | 'TigrinyaEritrean' => 'ti_ER', | ||||
| 178 | ); | ||||
| 179 | |||||
| 180 | # spent 5.64ms (31µs+5.61) within DateTime::Locale::load which was called:
# once (31µs+5.61ms) by DateTime::DefaultLocale at line 99 of DateTime.pm | ||||
| 181 | 1 | 1µs | my $class = shift; | ||
| 182 | 1 | 49µs | 1 | 42µs | my ($name) = validate_pos( @_, { type => SCALAR } ); # spent 42µs making 1 call to Params::Validate::_validate_pos # spent 4µs executing statements in string eval |
| 183 | |||||
| 184 | # Support RFC 3066 language tags, which use '-' instead of '_'. | ||||
| 185 | 1 | 1µs | $name =~ tr/-/_/; | ||
| 186 | |||||
| 187 | 1 | 600ns | my $key = $name; | ||
| 188 | |||||
| 189 | 1 | 700ns | return $LoadCache{$key} if exists $LoadCache{$key}; | ||
| 190 | |||||
| 191 | # Custom class registered by user | ||||
| 192 | 1 | 3µs | if ( $Class{$name} ) { | ||
| 193 | return $LoadCache{$key} | ||||
| 194 | = $class->_load_class_from_id( $name, $Class{$name} ); | ||||
| 195 | } | ||||
| 196 | |||||
| 197 | # special case for backwards compatibility with DT::Language | ||||
| 198 | 1 | 700ns | $name = $OldAliases{$name} if exists $OldAliases{$name}; | ||
| 199 | |||||
| 200 | 1 | 26µs | 1 | 5.57ms | if ( exists $DataForID{$name} || exists $AliasToID{$name} ) { # spent 5.57ms making 1 call to DateTime::Locale::_load_class_from_id |
| 201 | return $LoadCache{$key} = $class->_load_class_from_id($name); | ||||
| 202 | } | ||||
| 203 | |||||
| 204 | foreach my $h ( \%NameToID, \%NativeNameToID ) { | ||||
| 205 | return $LoadCache{$key} = $class->_load_class_from_id( $h->{$name} ) | ||||
| 206 | if exists $h->{$name}; | ||||
| 207 | } | ||||
| 208 | |||||
| 209 | if ( my $id = $class->_guess_id($name) ) { | ||||
| 210 | return $LoadCache{$key} = $class->_load_class_from_id($id); | ||||
| 211 | } | ||||
| 212 | |||||
| 213 | die "Invalid locale name or id: $name\n"; | ||||
| 214 | } | ||||
| 215 | |||||
| 216 | sub _guess_id { | ||||
| 217 | my $class = shift; | ||||
| 218 | my $name = shift; | ||||
| 219 | |||||
| 220 | # Strip off charset for LC_* ids : en_GB.UTF-8 etc | ||||
| 221 | $name =~ s/\..*$//; | ||||
| 222 | |||||
| 223 | my ( $language, $script, $territory, $variant ) = _parse_id($name); | ||||
| 224 | |||||
| 225 | my @guesses; | ||||
| 226 | |||||
| 227 | if ( defined $script ) { | ||||
| 228 | my $guess = join '_', lc $language, ucfirst lc $script; | ||||
| 229 | |||||
| 230 | push @guesses, $guess; | ||||
| 231 | |||||
| 232 | $guess .= '_' . uc $territory if defined $territory; | ||||
| 233 | |||||
| 234 | # version with script comes first | ||||
| 235 | unshift @guesses, $guess; | ||||
| 236 | } | ||||
| 237 | |||||
| 238 | if ( defined $variant ) { | ||||
| 239 | push @guesses, join '_', lc $language, uc $territory, uc $variant; | ||||
| 240 | } | ||||
| 241 | |||||
| 242 | if ( defined $territory ) { | ||||
| 243 | push @guesses, join '_', lc $language, uc $territory; | ||||
| 244 | } | ||||
| 245 | |||||
| 246 | push @guesses, lc $language; | ||||
| 247 | |||||
| 248 | foreach my $id (@guesses) { | ||||
| 249 | return $id | ||||
| 250 | if exists $DataForID{$id} || exists $AliasToID{$id}; | ||||
| 251 | } | ||||
| 252 | } | ||||
| 253 | |||||
| 254 | sub _parse_id { | ||||
| 255 | $_[0] =~ /([a-z]+) # id | ||||
| 256 | (?: _([A-Z][a-z]+) )? # script - Title Case - optional | ||||
| 257 | (?: _([A-Z]+) )? # territory - ALL CAPS - optional | ||||
| 258 | (?: _([A-Z]+) )? # variant - ALL CAPS - optional | ||||
| 259 | /x; | ||||
| 260 | |||||
| 261 | return $1, $2, $3, $4; | ||||
| 262 | } | ||||
| 263 | |||||
| 264 | # spent 5.57ms (630µs+4.94) within DateTime::Locale::_load_class_from_id which was called:
# once (630µs+4.94ms) by DateTime::Locale::load at line 200 | ||||
| 265 | 1 | 900ns | my $class = shift; | ||
| 266 | 1 | 700ns | my $id = shift; | ||
| 267 | 1 | 400ns | my $real_class = shift; | ||
| 268 | |||||
| 269 | # We want the first alias for which there is data, even if it has | ||||
| 270 | # no corresponding .pm file. There may be multiple levels of | ||||
| 271 | # alias to go through. | ||||
| 272 | 1 | 500ns | my $data_id = $id; | ||
| 273 | 1 | 2µs | while ( exists $AliasToID{$data_id} && !exists $DataForID{$data_id} ) { | ||
| 274 | $data_id = $AliasToID{$data_id}; | ||||
| 275 | } | ||||
| 276 | |||||
| 277 | 1 | 1µs | $real_class ||= "DateTime::Locale::$data_id"; | ||
| 278 | |||||
| 279 | 1 | 12µs | 1 | 2µs | unless ( $real_class->can('new') ) { # spent 2µs making 1 call to UNIVERSAL::can |
| 280 | 1 | 33µs | eval "require $real_class"; # spent 135µs executing statements in string eval | ||
| 281 | |||||
| 282 | 1 | 800ns | die $@ if $@; | ||
| 283 | } | ||||
| 284 | |||||
| 285 | my $locale = $real_class->new( | ||||
| 286 | 1 | 23µs | 1 | 45µs | %{ $DataForID{$data_id} }, # spent 45µs making 1 call to DateTime::Locale::Base::new |
| 287 | id => $id, | ||||
| 288 | ); | ||||
| 289 | |||||
| 290 | 1 | 600ns | return $locale if $DateTime::Locale::InGenerator; | ||
| 291 | |||||
| 292 | 1 | 13µs | 1 | 2µs | if ( $locale->can('cldr_version') ) { # spent 2µs making 1 call to UNIVERSAL::can |
| 293 | 1 | 2µs | 1 | 1µs | my $object_version = $locale->cldr_version(); # spent 1µs making 1 call to DateTime::Locale::en_US::cldr_version |
| 294 | 1 | 6µs | 1 | 4µs | my $catalog_version = DateTime::Locale::Catalog->CLDRVersion(); # spent 4µs making 1 call to DateTime::Locale::Catalog::CLDRVersion |
| 295 | |||||
| 296 | 1 | 1µs | if ( $object_version ne $catalog_version ) { | ||
| 297 | warn | ||||
| 298 | "Loaded $real_class, which is from an older version ($object_version)" | ||||
| 299 | . "of the CLDR database than this installation of" | ||||
| 300 | . "DateTime::Locale ($catalog_version).\n"; | ||||
| 301 | } | ||||
| 302 | } | ||||
| 303 | |||||
| 304 | 1 | 6µs | return $locale; | ||
| 305 | } | ||||
| 306 | |||||
| 307 | 1 | 11µs | 1; | ||
| 308 | |||||
| 309 | __END__ | ||||
# spent 828µs within DateTime::Locale::CORE:match which was called 466 times, avg 2µs/call:
# 466 times (828µs+0s) by DateTime::Locale::_register at line 62, avg 2µs/call |