| Filename | /usr/lib/x86_64-linux-gnu/perl5/5.26/Function/Parameters.pm | 
| Statements | Executed 195 statements in 4.68ms | 
| Calls | P | F | Exclusive Time | Inclusive Time | Subroutine | 
|---|---|---|---|---|---|
| 1 | 1 | 1 | 7.13ms | 7.52ms | Function::Parameters::BEGIN@6 | 
| 1 | 1 | 1 | 1.76ms | 2.26ms | Function::Parameters::BEGIN@7 | 
| 1 | 1 | 1 | 166µs | 322µs | Function::Parameters::import | 
| 3 | 1 | 1 | 82µs | 82µs | Function::Parameters::CORE:regcomp (opcode) | 
| 3 | 2 | 1 | 27µs | 117µs | Function::Parameters::_assert_valid_identifier | 
| 4 | 4 | 1 | 27µs | 27µs | Function::Parameters::_register_info | 
| 1 | 1 | 1 | 23µs | 23µs | Function::Parameters::BEGIN@3 | 
| 6 | 3 | 1 | 19µs | 19µs | Function::Parameters::CORE:match (opcode) | 
| 14 | 7 | 1 | 18µs | 18µs | Function::Parameters::_delete_default | 
| 1 | 1 | 1 | 12µs | 20µs | Function::Parameters::BEGIN@4 | 
| 1 | 1 | 1 | 12µs | 28µs | Function::Parameters::BEGIN@80 | 
| 1 | 1 | 1 | 11µs | 268µs | Function::Parameters::BEGIN@15 | 
| 1 | 1 | 1 | 9µs | 9µs | Function::Parameters::BEGIN@14 | 
| 1 | 1 | 1 | 7µs | 7µs | Function::Parameters::CORE:sort (opcode) | 
| 1 | 1 | 1 | 4µs | 11µs | Function::Parameters::_assert_valid_attributes | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::__ANON__[:104] | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::__ANON__[:95] | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_croak | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_find_or_add_idx | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_malformed_type | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_mkparam1 | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_mkparams | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_reify_type_auto | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_reify_type_auto_term | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_reify_type_auto_union | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::_reify_type_moose | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::info | 
| 0 | 0 | 0 | 0s | 0s | Function::Parameters::unimport | 
| Line | State ments | Time on line | Calls | Time in subs | Code | 
|---|---|---|---|---|---|
| 1 | package Function::Parameters; | ||||
| 2 | |||||
| 3 | 2 | 70µs | 1 | 23µs | # spent 23µs within Function::Parameters::BEGIN@3 which was called:
#    once (23µs+0s) by main::BEGIN@31 at line 3 # spent    23µs making 1 call to Function::Parameters::BEGIN@3 | 
| 4 | 2 | 48µs | 2 | 29µs | # spent 20µs (12+9) within Function::Parameters::BEGIN@4 which was called:
#    once (12µs+9µs) by main::BEGIN@31 at line 4 # spent    20µs making 1 call to Function::Parameters::BEGIN@4
# spent     9µs making 1 call to warnings::import | 
| 5 | |||||
| 6 | 2 | 203µs | 2 | 7.60ms | # spent 7.52ms (7.13+388µs) within Function::Parameters::BEGIN@6 which was called:
#    once (7.13ms+388µs) by main::BEGIN@31 at line 6 # spent  7.52ms making 1 call to Function::Parameters::BEGIN@6
# spent    85µs making 1 call to Exporter::import | 
| 7 | 2 | 250µs | 2 | 2.33ms | # spent 2.26ms (1.76+500µs) within Function::Parameters::BEGIN@7 which was called:
#    once (1.76ms+500µs) by main::BEGIN@31 at line 7 # spent  2.26ms making 1 call to Function::Parameters::BEGIN@7
# spent    70µs making 1 call to Exporter::import | 
| 8 | |||||
| 9 | sub _croak { | ||||
| 10 | my (undef, $file, $line) = caller 1; | ||||
| 11 | die @_, " at $file line $line.\n"; | ||||
| 12 | } | ||||
| 13 | |||||
| 14 | 2 | 57µs | 1 | 9µs | # spent 9µs within Function::Parameters::BEGIN@14 which was called:
#    once (9µs+0s) by main::BEGIN@31 at line 14 # spent     9µs making 1 call to Function::Parameters::BEGIN@14 | 
| 15 | # spent 268µs (11+257) within Function::Parameters::BEGIN@15 which was called:
#    once (11µs+257µs) by main::BEGIN@31 at line 19 | ||||
| 16 | 1 | 500ns | our $VERSION = '2.001003'; | ||
| 17 | #$VERSION =~ s/-TRIAL[0-9]*\z//; | ||||
| 18 | 1 | 266µs | 1 | 257µs | XSLoader::load;     # spent   257µs making 1 call to XSLoader::load | 
| 19 | 1 | 633µs | 1 | 268µs | } # spent   268µs making 1 call to Function::Parameters::BEGIN@15 | 
| 20 | |||||
| 21 | sub _assert_valid_identifier { | ||||
| 22 | 3 | 2µs | my ($name, $with_dollar) = @_; | ||
| 23 | 3 | 2µs | my $bonus = $with_dollar ? '\$' : ''; | ||
| 24 | 3 | 116µs | 6 | 89µs | $name =~ /\A${bonus}[^\W\d]\w*\z/     # spent    82µs making 3 calls to Function::Parameters::CORE:regcomp, avg 27µs/call
    # spent     8µs making 3 calls to Function::Parameters::CORE:match, avg 3µs/call | 
| 25 | or confess qq{"$name" doesn't look like a valid identifier}; | ||||
| 26 | } | ||||
| 27 | |||||
| 28 | # spent 11µs (4+7) within Function::Parameters::_assert_valid_attributes which was called:
#    once (4µs+7µs) by Function::Parameters::import at line 280 | ||||
| 29 | 1 | 500ns | my ($attrs) = @_; | ||
| 30 | 1 | 12µs | 1 | 7µs | $attrs =~ m{     # spent     7µs making 1 call to Function::Parameters::CORE:match | 
| 31 | \A \s*+ | ||||
| 32 | : \s*+ | ||||
| 33 | (?&ident) (?! [^\s:(] ) (?¶m)?+ \s*+ | ||||
| 34 | (?: | ||||
| 35 | (?: : \s*+ )? | ||||
| 36 | (?&ident) (?! [^\s:(] ) (?¶m)?+ \s*+ | ||||
| 37 | )*+ | ||||
| 38 | \z | ||||
| 39 | |||||
| 40 | (?(DEFINE) | ||||
| 41 | (?<ident> | ||||
| 42 | [^\W\d] | ||||
| 43 | \w*+ | ||||
| 44 | ) | ||||
| 45 | (?<param> | ||||
| 46 | \( | ||||
| 47 | [^()\\]*+ | ||||
| 48 | (?: | ||||
| 49 | (?: | ||||
| 50 | \\ . | ||||
| 51 | | | ||||
| 52 | (?¶m) | ||||
| 53 | ) | ||||
| 54 | [^()\\]*+ | ||||
| 55 | )*+ | ||||
| 56 | \) | ||||
| 57 | ) | ||||
| 58 | ) | ||||
| 59 | }sx or confess qq{"$attrs" doesn't look like valid attributes}; | ||||
| 60 | } | ||||
| 61 | |||||
| 62 | sub _reify_type_moose { | ||||
| 63 | require Moose::Util::TypeConstraints; | ||||
| 64 | Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($_[0]) | ||||
| 65 | } | ||||
| 66 | |||||
| 67 | sub _malformed_type { | ||||
| 68 | my ($type, $msg) = @_; | ||||
| 69 | my $pos = pos $_[0]; | ||||
| 70 | substr $type, $pos, 0, ' <-- HERE '; | ||||
| 71 | croak "Malformed type: $msg marked by <-- HERE in '$type'"; | ||||
| 72 | } | ||||
| 73 | |||||
| 74 | sub _reify_type_auto_term { | ||||
| 75 | # (str, caller) | ||||
| 76 | $_[0] =~ /\G ( \w+ (?: :: \w+)* ) \s* /xgc or _malformed_type $_[0], "missing type name"; | ||||
| 77 | my $name = $1; | ||||
| 78 | $name = "$_[1]::$name" unless $name =~ /::/; | ||||
| 79 | my $fun = do { | ||||
| 80 | 2 | 2.71ms | 2 | 45µs | # spent 28µs (12+17) within Function::Parameters::BEGIN@80 which was called:
#    once (12µs+17µs) by main::BEGIN@31 at line 80         # spent    28µs making 1 call to Function::Parameters::BEGIN@80
        # spent    17µs making 1 call to strict::unimport | 
| 81 | defined &$name or croak "Undefined type name $name"; | ||||
| 82 | \&$name | ||||
| 83 | }; | ||||
| 84 | |||||
| 85 | $_[0] =~ /\G \[ \s* /xgc | ||||
| 86 | or return $fun; | ||||
| 87 | |||||
| 88 | my @args; | ||||
| 89 | until ($_[0] =~ /\G \] \s* /xgc) { | ||||
| 90 | $_[0] =~ /\G , \s* /xgc or _malformed_type $_[0], "missing ',' or ']'" | ||||
| 91 | if @args; | ||||
| 92 | push @args, &_reify_type_auto_union; | ||||
| 93 | } | ||||
| 94 | |||||
| 95 | sub { $fun->([map $_->(), @args]) } | ||||
| 96 | } | ||||
| 97 | |||||
| 98 | sub _reify_type_auto_union { | ||||
| 99 | # (str, caller) | ||||
| 100 | my $fun = &_reify_type_auto_term; | ||||
| 101 | while ($_[0] =~ /\G \| \s* /xgc) { | ||||
| 102 | my $right = &_reify_type_auto_term; | ||||
| 103 | my $left = $fun; | ||||
| 104 | $fun = sub { $left->() | $right->() }; | ||||
| 105 | } | ||||
| 106 | $fun | ||||
| 107 | } | ||||
| 108 | |||||
| 109 | sub _reify_type_auto { | ||||
| 110 | my ($type) = @_; | ||||
| 111 | my $caller = caller; | ||||
| 112 | |||||
| 113 | $type =~ /\G \s+ /xgc; | ||||
| 114 | my $tfun = _reify_type_auto_union $type, $caller; | ||||
| 115 | $type =~ /\G \z/xgc or _malformed_type $type, "trailing garbage"; | ||||
| 116 | $tfun->() | ||||
| 117 | } | ||||
| 118 | |||||
| 119 | # spent 18µs within Function::Parameters::_delete_default which was called 14 times, avg 1µs/call:
# 2 times (5µs+0s) by Function::Parameters::import at line 338, avg 2µs/call
# 2 times (3µs+0s) by Function::Parameters::import at line 341, avg 1µs/call
# 2 times (3µs+0s) by Function::Parameters::import at line 339, avg 1µs/call
# 2 times (2µs+0s) by Function::Parameters::import at line 340, avg 1µs/call
# 2 times (2µs+0s) by Function::Parameters::import at line 343, avg 950ns/call
# 2 times (2µs+0s) by Function::Parameters::import at line 342, avg 900ns/call
# 2 times (2µs+0s) by Function::Parameters::import at line 344, avg 800ns/call | ||||
| 120 | 14 | 4µs | my ($href, $key, $default) = @_; | ||
| 121 | 14 | 28µs | exists $href->{$key} ? delete $href->{$key} : $default | ||
| 122 | } | ||||
| 123 | |||||
| 124 | sub _find_or_add_idx { | ||||
| 125 | my ($array, $x) = @_; | ||||
| 126 | my $index; | ||||
| 127 | for my $i (0 .. $#$array) { | ||||
| 128 | if ($array->[$i] == $x) { | ||||
| 129 | $index = $i; | ||||
| 130 | last; | ||||
| 131 | } | ||||
| 132 | } | ||||
| 133 | unless (defined $index) { | ||||
| 134 | $index = @$array; | ||||
| 135 | push @$array, $x; | ||||
| 136 | } | ||||
| 137 | $index | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | 1 | 28µs | my %type_map = ( | ||
| 141 | function_strict => {}, | ||||
| 142 | function_lax => { | ||||
| 143 | defaults => 'function_strict', | ||||
| 144 | strict => 0, | ||||
| 145 | }, | ||||
| 146 | function => { defaults => 'function_strict' }, | ||||
| 147 | |||||
| 148 | method_strict => { | ||||
| 149 | defaults => 'function_strict', | ||||
| 150 | attributes => ':method', | ||||
| 151 | shift => '$self', | ||||
| 152 | invocant => 1, | ||||
| 153 | }, | ||||
| 154 | method_lax => { | ||||
| 155 | defaults => 'method_strict', | ||||
| 156 | strict => 0, | ||||
| 157 | }, | ||||
| 158 | method => { defaults => 'method_strict' }, | ||||
| 159 | |||||
| 160 | classmethod_strict => { | ||||
| 161 | defaults => 'method_strict', | ||||
| 162 | shift => '$class', | ||||
| 163 | }, | ||||
| 164 | classmethod_lax => { | ||||
| 165 | defaults => 'classmethod_strict', | ||||
| 166 | strict => 0, | ||||
| 167 | }, | ||||
| 168 | classmethod => { defaults => 'classmethod_strict' }, | ||||
| 169 | |||||
| 170 | around => { | ||||
| 171 | defaults => 'method', | ||||
| 172 | name => 'required', | ||||
| 173 | install_sub => 'around', | ||||
| 174 | shift => ['$orig', '$self'], | ||||
| 175 | runtime => 1, | ||||
| 176 | }, | ||||
| 177 | ( | ||||
| 178 | map +( | ||||
| 179 | $_ => { | ||||
| 180 | defaults => 'method', | ||||
| 181 | name => 'required', | ||||
| 182 | install_sub => $_, | ||||
| 183 | runtime => 1, | ||||
| 184 | } | ||||
| 185 | ), qw( | ||||
| 186 | before after augment override | ||||
| 187 | ), | ||||
| 188 | ), | ||||
| 189 | ); | ||||
| 190 | |||||
| 191 | 1 | 11µs | my %import_map = ( | ||
| 192 | fun => 'function', | ||||
| 193 | ( | ||||
| 194 | map +($_ => $_), | ||||
| 195 | qw( | ||||
| 196 | method | ||||
| 197 | classmethod | ||||
| 198 | before | ||||
| 199 | after | ||||
| 200 | around | ||||
| 201 | augment | ||||
| 202 | override | ||||
| 203 | ) | ||||
| 204 | ), | ||||
| 205 | |||||
| 206 | ':strict' => { | ||||
| 207 | fun => 'function_strict', | ||||
| 208 | method => 'method_strict', | ||||
| 209 | }, | ||||
| 210 | |||||
| 211 | ':lax' => { | ||||
| 212 | fun => 'function_lax', | ||||
| 213 | method => 'method_lax', | ||||
| 214 | }, | ||||
| 215 | |||||
| 216 | ':std' => [qw(fun method)], | ||||
| 217 | ':modifiers' => [qw( | ||||
| 218 | before | ||||
| 219 | after | ||||
| 220 | around | ||||
| 221 | augment | ||||
| 222 | override | ||||
| 223 | )], | ||||
| 224 | ); | ||||
| 225 | 1 | 2µs | for my $v (values %import_map) { | ||
| 226 | 12 | 7µs | if (ref $v eq 'ARRAY') { | ||
| 227 | $v = { | ||||
| 228 | 2 | 10µs | map +($_ => $import_map{$_} || die "Internal error: $v => $_"), | ||
| 229 | @$v | ||||
| 230 | }; | ||||
| 231 | } | ||||
| 232 | } | ||||
| 233 | |||||
| 234 | # spent 322µs (166+157) within Function::Parameters::import which was called:
#    once (166µs+157µs) by main::BEGIN@31 at line 31 of /homes/dcw/public_html/PSD/article13/v11.pl | ||||
| 235 | 1 | 700ns | my $class = shift; | ||
| 236 | |||||
| 237 | 1 | 300ns | my %imports; | ||
| 238 | 1 | 2µs | @_ = qw(:std) if !@_; | ||
| 239 | 1 | 800ns | for my $item (@_) { | ||
| 240 | 1 | 200ns | my $part; | ||
| 241 | 1 | 600ns | if (ref $item) { | ||
| 242 | $part = $item; | ||||
| 243 | } else { | ||||
| 244 | 1 | 800ns | my $type = $import_map{$item} | ||
| 245 | or croak qq{"$item" is not exported by the $class module}; | ||||
| 246 | 1 | 900ns | $part = ref $type | ||
| 247 | ? $type | ||||
| 248 | : { $item => $type }; | ||||
| 249 | } | ||||
| 250 | 1 | 4µs | @imports{keys %$part} = values %$part; | ||
| 251 | } | ||||
| 252 | |||||
| 253 | 1 | 200ns | my %spec; | ||
| 254 | |||||
| 255 | 1 | 17µs | 1 | 7µs | for my $name (sort keys %imports) {     # spent     7µs making 1 call to Function::Parameters::CORE:sort | 
| 256 | 2 | 4µs | 2 | 69µs | _assert_valid_identifier $name;         # spent    69µs making 2 calls to Function::Parameters::_assert_valid_identifier, avg 35µs/call | 
| 257 | 2 | 1µs | my $proto_type = $imports{$name}; | ||
| 258 | |||||
| 259 | 2 | 4µs | $proto_type = {defaults => $proto_type} unless ref $proto_type; | ||
| 260 | |||||
| 261 | 2 | 4µs | my %type = %$proto_type; | ||
| 262 | 2 | 7µs | while (my $defaults = delete $type{defaults}) { | ||
| 263 | 5 | 3µs | my $base = $type_map{$defaults} | ||
| 264 | or confess qq["$defaults" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})]; | ||||
| 265 | 5 | 10µs | %type = (%$base, %type); | ||
| 266 | } | ||||
| 267 | |||||
| 268 | 2 | 500ns | if (exists $type{strict}) { | ||
| 269 | $type{check_argument_count} ||= $type{strict}; | ||||
| 270 | delete $type{strict}; | ||||
| 271 | } | ||||
| 272 | |||||
| 273 | 2 | 400ns | my %clean; | ||
| 274 | |||||
| 275 | 2 | 2µs | $clean{name} = delete $type{name} // 'optional'; | ||
| 276 | 2 | 9µs | 2 | 4µs | $clean{name} =~ /\A(?:optional|required|prohibited)\z/         # spent     4µs making 2 calls to Function::Parameters::CORE:match, avg 2µs/call | 
| 277 | or confess qq["$clean{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)]; | ||||
| 278 | |||||
| 279 | 2 | 2µs | $clean{attrs} = delete $type{attributes} // ''; | ||
| 280 | 2 | 2µs | 1 | 11µs | _assert_valid_attributes $clean{attrs} if $clean{attrs};         # spent    11µs making 1 call to Function::Parameters::_assert_valid_attributes | 
| 281 | |||||
| 282 | 2 | 3µs | if (!exists $type{reify_type}) { | ||
| 283 | $clean{reify_type} = \&_reify_type_auto; | ||||
| 284 | } else { | ||||
| 285 | my $rt = delete $type{reify_type} // '(undef)'; | ||||
| 286 | if (!ref $rt) { | ||||
| 287 | $rt = | ||||
| 288 | $rt eq 'auto' ? \&_reify_type_auto : | ||||
| 289 | $rt eq 'moose' ? \&_reify_type_moose : | ||||
| 290 | confess qq{"$rt" isn't a known predefined type reifier}; | ||||
| 291 | } elsif (ref $rt ne 'CODE') { | ||||
| 292 | confess qq{"$rt" doesn't look like a type reifier}; | ||||
| 293 | } | ||||
| 294 | |||||
| 295 | $clean{reify_type} = $rt; | ||||
| 296 | } | ||||
| 297 | |||||
| 298 | 2 | 1µs | if (!exists $type{install_sub}) { | ||
| 299 | $clean{install_sub} = ''; | ||||
| 300 | } else { | ||||
| 301 | my $is = delete $type{install_sub}; | ||||
| 302 | if (!ref $is) { | ||||
| 303 | _assert_valid_identifier $is; | ||||
| 304 | } elsif (ref $is ne 'CODE') { | ||||
| 305 | confess qq{"$is" doesn't look like a sub installer}; | ||||
| 306 | } | ||||
| 307 | |||||
| 308 | $clean{install_sub} = $is; | ||||
| 309 | } | ||||
| 310 | |||||
| 311 | 2 | 1µs | $clean{shift} = do { | ||
| 312 | 2 | 2µs | my $shift = delete $type{shift} // []; | ||
| 313 | 2 | 2µs | $shift = [$shift] if !ref $shift; | ||
| 314 | 2 | 500ns | my $str = ''; | ||
| 315 | 2 | 600ns | my @shifty_types; | ||
| 316 | 2 | 1µs | for my $item (@$shift) { | ||
| 317 | 1 | 300ns | my ($name, $type); | ||
| 318 | 1 | 400ns | if (ref $item) { | ||
| 319 | @$item == 2 or confess "A 'shift' item must have 2 elements, not " . @$item; | ||||
| 320 | ($name, $type) = @$item; | ||||
| 321 | } else { | ||||
| 322 | 1 | 400ns | $name = $item; | ||
| 323 | } | ||||
| 324 | 1 | 2µs | 1 | 47µs | _assert_valid_identifier $name, 1;                 # spent    47µs making 1 call to Function::Parameters::_assert_valid_identifier | 
| 325 | 1 | 400ns | $name eq '$_' and confess q[Using "$_" as a parameter is not supported]; | ||
| 326 | 1 | 800ns | $str .= $name; | ||
| 327 | 1 | 300ns | if (defined $type) { | ||
| 328 | blessed($type) or confess "${name}'s type must be an object, not $type"; | ||||
| 329 | my $index = _find_or_add_idx \@shifty_types, $type; | ||||
| 330 | $str .= "/$index"; | ||||
| 331 | } | ||||
| 332 | 1 | 15µs | $str .= ' '; | ||
| 333 | } | ||||
| 334 | 2 | 1µs | $clean{shift_types} = \@shifty_types; | ||
| 335 | 2 | 2µs | $str | ||
| 336 | }; | ||||
| 337 | |||||
| 338 | 2 | 4µs | 2 | 5µs | $clean{default_arguments}    = _delete_default \%type, 'default_arguments',    1;         # spent     5µs making 2 calls to Function::Parameters::_delete_default, avg 2µs/call | 
| 339 | 2 | 4µs | 2 | 3µs | $clean{named_parameters}     = _delete_default \%type, 'named_parameters',     1;         # spent     3µs making 2 calls to Function::Parameters::_delete_default, avg 1µs/call | 
| 340 | 2 | 2µs | 2 | 2µs | $clean{types}                = _delete_default \%type, 'types',                1;         # spent     2µs making 2 calls to Function::Parameters::_delete_default, avg 1µs/call | 
| 341 | 2 | 2µs | 2 | 3µs | $clean{invocant}             = _delete_default \%type, 'invocant',             0;         # spent     3µs making 2 calls to Function::Parameters::_delete_default, avg 1µs/call | 
| 342 | 2 | 2µs | 2 | 2µs | $clean{runtime}              = _delete_default \%type, 'runtime',              0;         # spent     2µs making 2 calls to Function::Parameters::_delete_default, avg 900ns/call | 
| 343 | 2 | 2µs | 2 | 2µs | $clean{check_argument_count} = _delete_default \%type, 'check_argument_count', 1;         # spent     2µs making 2 calls to Function::Parameters::_delete_default, avg 950ns/call | 
| 344 | 2 | 2µs | 2 | 2µs | $clean{check_argument_types} = _delete_default \%type, 'check_argument_types', 1;         # spent     2µs making 2 calls to Function::Parameters::_delete_default, avg 800ns/call | 
| 345 | |||||
| 346 | 2 | 500ns | %type and confess "Invalid keyword property: @{[sort keys %type]}"; | ||
| 347 | |||||
| 348 | 2 | 6µs | $spec{$name} = \%clean; | ||
| 349 | } | ||||
| 350 | |||||
| 351 | 1 | 2µs | my %config = %{$^H{+HINTK_CONFIG} // {}}; | ||
| 352 | 1 | 1µs | for my $kw (keys %spec) { | ||
| 353 | 2 | 700ns | my $type = $spec{$kw}; | ||
| 354 | |||||
| 355 | my $flags = | ||||
| 356 | $type->{name} eq 'prohibited' ? FLAG_ANON_OK : | ||||
| 357 | 2 | 1µs | $type->{name} eq 'required' ? FLAG_NAME_OK : | ||
| 358 | FLAG_ANON_OK | FLAG_NAME_OK | ||||
| 359 | ; | ||||
| 360 | 2 | 700ns | $flags |= FLAG_DEFAULT_ARGS if $type->{default_arguments}; | ||
| 361 | 2 | 500ns | $flags |= FLAG_CHECK_NARGS if $type->{check_argument_count}; | ||
| 362 | 2 | 600ns | $flags |= FLAG_CHECK_TARGS if $type->{check_argument_types}; | ||
| 363 | 2 | 500ns | $flags |= FLAG_INVOCANT if $type->{invocant}; | ||
| 364 | 2 | 500ns | $flags |= FLAG_NAMED_PARAMS if $type->{named_parameters}; | ||
| 365 | 2 | 400ns | $flags |= FLAG_TYPES_OK if $type->{types}; | ||
| 366 | 2 | 400ns | $flags |= FLAG_RUNTIME if $type->{runtime}; | ||
| 367 | $config{$kw} = { | ||||
| 368 | HINTSK_FLAGS, => $flags, | ||||
| 369 | HINTSK_SHIFT, => $type->{shift}, | ||||
| 370 | HINTSK_ATTRS, => $type->{attrs}, | ||||
| 371 | HINTSK_REIFY, => $type->{reify_type}, | ||||
| 372 | HINTSK_INSTL, => $type->{install_sub}, | ||||
| 373 | !@{$type->{shift_types}} ? () : ( | ||||
| 374 | HINTSK_SHIF2, => $type->{shift_types}, | ||||
| 375 | 2 | 6µs | ), | ||
| 376 | }; | ||||
| 377 | } | ||||
| 378 | 1 | 10µs | $^H{+HINTK_CONFIG} = \%config; | ||
| 379 | } | ||||
| 380 | |||||
| 381 | sub unimport { | ||||
| 382 | my $class = shift; | ||||
| 383 | |||||
| 384 | if (!@_) { | ||||
| 385 | delete $^H{+HINTK_CONFIG}; | ||||
| 386 | return; | ||||
| 387 | } | ||||
| 388 | |||||
| 389 | my %config = %{$^H{+HINTK_CONFIG}}; | ||||
| 390 | delete @config{@_}; | ||||
| 391 | $^H{+HINTK_CONFIG} = \%config; | ||||
| 392 | } | ||||
| 393 | |||||
| 394 | |||||
| 395 | our %metadata; | ||||
| 396 | |||||
| 397 | # spent 27µs within Function::Parameters::_register_info which was called 4 times, avg 7µs/call:
#    once (8µs+0s) by main::NULL at line 125 of /homes/dcw/public_html/PSD/article13/v11.pl
#    once (7µs+0s) by main::NULL at line 139 of /homes/dcw/public_html/PSD/article13/v11.pl
#    once (6µs+0s) by main::NULL at line 154 of /homes/dcw/public_html/PSD/article13/v11.pl
#    once (6µs+0s) by main::NULL at line 214 of /homes/dcw/public_html/PSD/article13/v11.pl | ||||
| 398 | my ( | ||||
| 399 | 4 | 5µs | $key, | ||
| 400 | $declarator, | ||||
| 401 | $shift, | ||||
| 402 | $positional_required, | ||||
| 403 | $positional_optional, | ||||
| 404 | $named_required, | ||||
| 405 | $named_optional, | ||||
| 406 | $slurpy, | ||||
| 407 | $slurpy_type, | ||||
| 408 | ) = @_; | ||||
| 409 | |||||
| 410 | 4 | 11µs | my $info = { | ||
| 411 | declarator => $declarator, | ||||
| 412 | shift => $shift, | ||||
| 413 | positional_required => $positional_required, | ||||
| 414 | positional_optional => $positional_optional, | ||||
| 415 | named_required => $named_required, | ||||
| 416 | named_optional => $named_optional, | ||||
| 417 | slurpy => defined $slurpy ? [$slurpy, $slurpy_type] : undef, | ||||
| 418 | }; | ||||
| 419 | |||||
| 420 | 4 | 20µs | $metadata{$key} = $info; | ||
| 421 | } | ||||
| 422 | |||||
| 423 | sub _mkparam1 { | ||||
| 424 | my ($pair) = @_; | ||||
| 425 | my ($v, $t) = @{$pair || []} or return undef; | ||||
| 426 | Function::Parameters::Param->new( | ||||
| 427 | name => $v, | ||||
| 428 | type => $t, | ||||
| 429 | ) | ||||
| 430 | } | ||||
| 431 | |||||
| 432 | sub _mkparams { | ||||
| 433 | my @r; | ||||
| 434 | while (my ($v, $t) = splice @_, 0, 2) { | ||||
| 435 | push @r, Function::Parameters::Param->new( | ||||
| 436 | name => $v, | ||||
| 437 | type => $t, | ||||
| 438 | ); | ||||
| 439 | } | ||||
| 440 | \@r | ||||
| 441 | } | ||||
| 442 | |||||
| 443 | sub info { | ||||
| 444 | my ($func) = @_; | ||||
| 445 | my $key = _cv_root $func or return undef; | ||||
| 446 | my $info = $metadata{$key} or return undef; | ||||
| 447 | require Function::Parameters::Info; | ||||
| 448 | Function::Parameters::Info->new( | ||||
| 449 | keyword => $info->{declarator}, | ||||
| 450 | nshift => $info->{shift}, | ||||
| 451 | slurpy => _mkparam1($info->{slurpy}), | ||||
| 452 | ( | ||||
| 453 | map +("_$_" => _mkparams @{$info->{$_}}), | ||||
| 454 | qw( | ||||
| 455 | positional_required | ||||
| 456 | positional_optional | ||||
| 457 | named_required | ||||
| 458 | named_optional | ||||
| 459 | ) | ||||
| 460 | ) | ||||
| 461 | ) | ||||
| 462 | } | ||||
| 463 | |||||
| 464 | 1 | 25µs | 'ok' | ||
| 465 | |||||
| 466 | __END__ | ||||
| # spent 19µs within Function::Parameters::CORE:match which was called 6 times, avg 3µs/call:
# 3 times (8µs+0s) by Function::Parameters::_assert_valid_identifier at line 24, avg 3µs/call
# 2 times (4µs+0s) by Function::Parameters::import at line 276, avg 2µs/call
#    once (7µs+0s) by Function::Parameters::_assert_valid_attributes at line 30 | |||||
| # spent 82µs within Function::Parameters::CORE:regcomp which was called 3 times, avg 27µs/call:
# 3 times (82µs+0s) by Function::Parameters::_assert_valid_identifier at line 24, avg 27µs/call | |||||
| # spent 7µs within Function::Parameters::CORE:sort which was called:
#    once (7µs+0s) by Function::Parameters::import at line 255 |