| Filename | /home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm |
| Statements | Executed 59306 statements in 560ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 233 | 1 | 1 | 146ms | 1.16s | Sub::Exporter::_do_import |
| 598 | 2 | 1 | 85.9ms | 233ms | Sub::Exporter::_expand_groups (recurses: max depth 2, inclusive time 238ms) |
| 233 | 3 | 2 | 81.1ms | 495ms | Sub::Exporter::default_installer |
| 2013 | 1 | 1 | 81.1ms | 224ms | Sub::Exporter::default_generator |
| 2743 | 2 | 1 | 38.9ms | 38.9ms | Sub::Exporter::_group_name |
| 365 | 1 | 1 | 37.5ms | 204ms | Sub::Exporter::_expand_group (recurses: max depth 1, inclusive time 148ms) |
| 233 | 22 | 19 | 33.3ms | 1.47s | Sub::Exporter::__ANON__[:756] |
| 233 | 1 | 1 | 20.2ms | 29.6ms | Sub::Exporter::_collect_collections |
| 45 | 1 | 1 | 9.34ms | 194ms | Sub::Exporter::_rewrite_build_config |
| 233 | 1 | 1 | 8.86ms | 8.86ms | Sub::Exporter::_mk_collection_builder |
| 45 | 1 | 1 | 3.91ms | 3.91ms | Sub::Exporter::_key_intersection |
| 45 | 4 | 3 | 2.18ms | 196ms | Sub::Exporter::build_exporter |
| 45 | 1 | 1 | 994µs | 1.00ms | Sub::Exporter::_assert_collector_names_ok |
| 3 | 1 | 1 | 366µs | 488µs | Sub::Exporter::__ANON__[:544] |
| 42 | 1 | 1 | 311µs | 311µs | Devel::GlobalDestruction::in_global_destruction (xsub) |
| 2 | 2 | 2 | 130µs | 2.85ms | Sub::Exporter::setup_exporter |
| 1 | 1 | 1 | 113µs | 113µs | Devel::GlobalDestruction::BEGIN@1 |
| 3 | 1 | 1 | 101µs | 101µs | Sub::Exporter::_setup |
| 3 | 1 | 1 | 68µs | 2.22ms | Sub::Exporter::__ANON__[:937] |
| 1 | 1 | 1 | 64µs | 64µs | Sub::Exporter::BEGIN@636 |
| 1 | 1 | 1 | 40µs | 90µs | Sub::Exporter::BEGIN@9 |
| 1 | 1 | 1 | 38µs | 56µs | Devel::GlobalDestruction::BEGIN@2 |
| 1 | 1 | 1 | 37µs | 106µs | Devel::GlobalDestruction::BEGIN@3 |
| 1 | 1 | 1 | 19µs | 19µs | Sub::Exporter::BEGIN@6 |
| 1 | 1 | 1 | 18µs | 18µs | Sub::Exporter::BEGIN@7 |
| 1 | 1 | 1 | 17µs | 17µs | Sub::Exporter::BEGIN@8 |
| 1 | 1 | 1 | 10µs | 10µs | Sub::Exporter::CORE:match (opcode) |
| 0 | 0 | 0 | 0s | 0s | Sub::Exporter::__ANON__[:773] |
| 0 | 0 | 0 | 0s | 0s | Sub::Exporter::default_exporter |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | 3 | 159µs | 1 | 113µs | # spent 113µs within Devel::GlobalDestruction::BEGIN@1 which was called:
# once (113µs+0s) by Devel::GlobalDestruction::BEGIN@26 at line 1 # spent 113µs making 1 call to Devel::GlobalDestruction::BEGIN@1 |
| 2 | 3 | 90µs | 2 | 74µs | # spent 56µs (38+18) within Devel::GlobalDestruction::BEGIN@2 which was called:
# once (38µs+18µs) by Devel::GlobalDestruction::BEGIN@26 at line 2 # spent 56µs making 1 call to Devel::GlobalDestruction::BEGIN@2
# spent 18µs making 1 call to strict::import |
| 3 | 3 | 123µs | 2 | 175µs | # spent 106µs (37+69) within Devel::GlobalDestruction::BEGIN@3 which was called:
# once (37µs+69µs) by Devel::GlobalDestruction::BEGIN@26 at line 3 # spent 106µs making 1 call to Devel::GlobalDestruction::BEGIN@3
# spent 69µs making 1 call to warnings::import |
| 4 | package Sub::Exporter; | ||||
| 5 | |||||
| 6 | 3 | 76µs | 1 | 19µs | # spent 19µs within Sub::Exporter::BEGIN@6 which was called:
# once (19µs+0s) by Devel::GlobalDestruction::BEGIN@26 at line 6 # spent 19µs making 1 call to Sub::Exporter::BEGIN@6 |
| 7 | 3 | 72µs | 1 | 18µs | # spent 18µs within Sub::Exporter::BEGIN@7 which was called:
# once (18µs+0s) by Devel::GlobalDestruction::BEGIN@26 at line 7 # spent 18µs making 1 call to Sub::Exporter::BEGIN@7 |
| 8 | 3 | 92µs | 1 | 17µs | # spent 17µs within Sub::Exporter::BEGIN@8 which was called:
# once (17µs+0s) by Devel::GlobalDestruction::BEGIN@26 at line 8 # spent 17µs making 1 call to Sub::Exporter::BEGIN@8 |
| 9 | 3 | 3.81ms | 2 | 139µs | # spent 90µs (40+50) within Sub::Exporter::BEGIN@9 which was called:
# once (40µs+50µs) by Devel::GlobalDestruction::BEGIN@26 at line 9 # spent 90µs making 1 call to Sub::Exporter::BEGIN@9
# spent 50µs making 1 call to UNIVERSAL::VERSION |
| 10 | |||||
| 11 | =head1 NAME | ||||
| 12 | |||||
| - - | |||||
| 21 | 1 | 4µs | our $VERSION = '0.982'; | ||
| 22 | |||||
| 23 | =head1 SYNOPSIS | ||||
| 24 | |||||
| - - | |||||
| 401 | # Given a potential import name, this returns the group name -- if it's got a | ||||
| 402 | # group prefix. | ||||
| 403 | sub _group_name { | ||||
| 404 | 6216 | 48.7ms | my ($name) = @_; | ||
| 405 | |||||
| 406 | return if (index q{-:}, (substr $name, 0, 1)) == -1; | ||||
| 407 | return substr $name, 1; | ||||
| 408 | } | ||||
| 409 | |||||
| 410 | # \@groups is a canonicalized opt list of exports and groups this returns | ||||
| 411 | # another canonicalized opt list with groups replaced with relevant exports. | ||||
| 412 | # \%seen is groups we've already expanded and can ignore. | ||||
| 413 | # \%merge is merged options from the group we're descending through. | ||||
| 414 | # spent 233ms (85.9+147) within Sub::Exporter::_expand_groups which was called 598 times, avg 390µs/call:
# 365 times (63.0ms+-63.0ms) by Sub::Exporter::_expand_group at line 509, avg 0s/call
# 233 times (22.9ms+210ms) by Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:756] at line 742, avg 1.00ms/call | ||||
| 415 | 3588 | 24.3ms | my ($class, $config, $groups, $collection, $seen, $merge) = @_; | ||
| 416 | $seen ||= {}; | ||||
| 417 | $merge ||= {}; | ||||
| 418 | my @groups = @$groups; | ||||
| 419 | |||||
| 420 | for my $i (reverse 0 .. $#groups) { | ||||
| 421 | 5121 | 54.4ms | 2378 | 33.6ms | if (my $group_name = _group_name($groups[$i][0])) { # spent 33.6ms making 2378 calls to Sub::Exporter::_group_name, avg 14µs/call |
| 422 | my $seen = { %$seen }; # faux-dynamic scoping | ||||
| 423 | |||||
| 424 | 365 | 204ms | splice @groups, $i, 1, # spent 352ms making 365 calls to Sub::Exporter::_expand_group, avg 965µs/call, recursion: max depth 1, sum of overlapping time 148ms | ||
| 425 | _expand_group($class, $config, $groups[$i], $collection, $seen, $merge); | ||||
| 426 | } else { | ||||
| 427 | # there's nothing to munge in this export's args | ||||
| 428 | next unless my %merge = %$merge; | ||||
| 429 | |||||
| 430 | # we have things to merge in; do so | ||||
| 431 | my $prefix = (delete $merge{-prefix}) || ''; | ||||
| 432 | my $suffix = (delete $merge{-suffix}) || ''; | ||||
| 433 | |||||
| 434 | if ( | ||||
| 435 | Params::Util::_CODELIKE($groups[$i][1]) ## no critic Private | ||||
| 436 | or | ||||
| 437 | Params::Util::_SCALAR0($groups[$i][1]) ## no critic Private | ||||
| 438 | ) { | ||||
| 439 | # this entry was build by a group generator | ||||
| 440 | $groups[$i][0] = $prefix . $groups[$i][0] . $suffix; | ||||
| 441 | } else { | ||||
| 442 | my $as | ||||
| 443 | = ref $groups[$i][1]{-as} ? $groups[$i][1]{-as} | ||||
| 444 | : $groups[$i][1]{-as} ? $prefix . $groups[$i][1]{-as} . $suffix | ||||
| 445 | : $prefix . $groups[$i][0] . $suffix; | ||||
| 446 | |||||
| 447 | $groups[$i][1] = { %{ $groups[$i][1] }, %merge, -as => $as }; | ||||
| 448 | } | ||||
| 449 | } | ||||
| 450 | } | ||||
| 451 | |||||
| 452 | return \@groups; | ||||
| 453 | } | ||||
| 454 | |||||
| 455 | # \@group is a name/value pair from an opt list. | ||||
| 456 | # spent 204ms (37.5+167) within Sub::Exporter::_expand_group which was called 365 times, avg 559µs/call:
# 365 times (37.5ms+167ms) by Sub::Exporter::_expand_groups at line 424, avg 559µs/call | ||||
| 457 | 3285 | 23.8ms | my ($class, $config, $group, $collection, $seen, $merge) = @_; | ||
| 458 | $merge ||= {}; | ||||
| 459 | |||||
| 460 | my ($group_name, $group_arg) = @$group; | ||||
| 461 | 365 | 5.30ms | $group_name = _group_name($group_name); # spent 5.30ms making 365 calls to Sub::Exporter::_group_name, avg 15µs/call | ||
| 462 | |||||
| 463 | Carp::croak qq(group "$group_name" is not exported by the $class module) | ||||
| 464 | unless exists $config->{groups}{$group_name}; | ||||
| 465 | |||||
| 466 | return if $seen->{$group_name}++; | ||||
| 467 | |||||
| 468 | if (ref $group_arg) { | ||||
| 469 | my $prefix = (delete $merge->{-prefix}||'') . ($group_arg->{-prefix}||''); | ||||
| 470 | my $suffix = ($group_arg->{-suffix}||'') . (delete $merge->{-suffix}||''); | ||||
| 471 | $merge = { | ||||
| 472 | %$merge, | ||||
| 473 | %$group_arg, | ||||
| 474 | ($prefix ? (-prefix => $prefix) : ()), | ||||
| 475 | ($suffix ? (-suffix => $suffix) : ()), | ||||
| 476 | }; | ||||
| 477 | } | ||||
| 478 | |||||
| 479 | my $exports = $config->{groups}{$group_name}; | ||||
| 480 | |||||
| 481 | 730 | 14.4ms | 730 | 4.21ms | if ( # spent 2.55ms making 365 calls to Params::Util::_CODELIKE, avg 7µs/call
# spent 1.65ms making 365 calls to Params::Util::_SCALAR0, avg 5µs/call |
| 482 | Params::Util::_CODELIKE($exports) ## no critic Private | ||||
| 483 | or | ||||
| 484 | Params::Util::_SCALAR0($exports) ## no critic Private | ||||
| 485 | ) { | ||||
| 486 | # I'm not very happy with this code for hiding -prefix and -suffix, but | ||||
| 487 | # it's needed, and I'm not sure, offhand, how to make it better. | ||||
| 488 | # -- rjbs, 2006-12-05 | ||||
| 489 | my $group_arg = $merge ? { %$merge } : {}; | ||||
| 490 | delete $group_arg->{-prefix}; | ||||
| 491 | delete $group_arg->{-suffix}; | ||||
| 492 | |||||
| 493 | my $group = Params::Util::_CODELIKE($exports) ## no critic Private | ||||
| 494 | ? $exports->($class, $group_name, $group_arg, $collection) | ||||
| 495 | : $class->$$exports($group_name, $group_arg, $collection); | ||||
| 496 | |||||
| 497 | Carp::croak qq(group generator "$group_name" did not return a hashref) | ||||
| 498 | if ref $group ne 'HASH'; | ||||
| 499 | |||||
| 500 | my $stuff = [ map { [ $_ => $group->{$_} ] } keys %$group ]; | ||||
| 501 | return @{ | ||||
| 502 | _expand_groups($class, $config, $stuff, $collection, $seen, $merge) | ||||
| 503 | }; | ||||
| 504 | } else { | ||||
| 505 | 365 | 66.9ms | $exports # spent 66.9ms making 365 calls to Data::OptList::mkopt, avg 183µs/call | ||
| 506 | = Data::OptList::mkopt($exports, "$group_name exports"); | ||||
| 507 | |||||
| 508 | return @{ | ||||
| 509 | 365 | 0s | _expand_groups($class, $config, $exports, $collection, $seen, $merge) # spent 238ms making 365 calls to Sub::Exporter::_expand_groups, avg 653µs/call, recursion: max depth 2, sum of overlapping time 238ms | ||
| 510 | }; | ||||
| 511 | } | ||||
| 512 | } | ||||
| 513 | |||||
| 514 | # spent 8.86ms within Sub::Exporter::_mk_collection_builder which was called 233 times, avg 38µs/call:
# 233 times (8.86ms+0s) by Sub::Exporter::_collect_collections at line 560, avg 38µs/call | ||||
| 515 | 932 | 9.87ms | my ($col, $etc) = @_; | ||
| 516 | my ($config, $import_args, $class, $into) = @$etc; | ||||
| 517 | |||||
| 518 | my %seen; | ||||
| 519 | # spent 488µs (366+121) within Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:544] which was called 3 times, avg 162µs/call:
# 3 times (366µs+121µs) by Sub::Exporter::_collect_collections at line 562, avg 162µs/call | ||||
| 520 | 15 | 113µs | my ($collection) = @_; | ||
| 521 | my ($name, $value) = @$collection; | ||||
| 522 | |||||
| 523 | Carp::croak "collection $name provided multiple times in import" | ||||
| 524 | if $seen{ $name }++; | ||||
| 525 | |||||
| 526 | 9 | 238µs | if (ref(my $hook = $config->{collectors}{$name})) { | ||
| 527 | my $arg = { | ||||
| 528 | name => $name, | ||||
| 529 | config => $config, | ||||
| 530 | import_args => $import_args, | ||||
| 531 | class => $class, | ||||
| 532 | into => $into, | ||||
| 533 | }; | ||||
| 534 | |||||
| 535 | my $error_msg = "collection $name failed validation"; | ||||
| 536 | 3 | 34µs | 3 | 20µs | if (Params::Util::_SCALAR0($hook)) { ## no critic Private # spent 20µs making 3 calls to Params::Util::_SCALAR0, avg 7µs/call |
| 537 | Carp::croak $error_msg unless $class->$$hook($value, $arg); | ||||
| 538 | } else { | ||||
| 539 | 3 | 101µs | Carp::croak $error_msg unless $hook->($value, $arg); # spent 101µs making 3 calls to Sub::Exporter::_setup, avg 34µs/call | ||
| 540 | } | ||||
| 541 | } | ||||
| 542 | |||||
| 543 | $col->{ $name } = $value; | ||||
| 544 | } | ||||
| 545 | } | ||||
| 546 | |||||
| 547 | # Given a config and pre-canonicalized importer args, remove collections from | ||||
| 548 | # the args and return them. | ||||
| 549 | # spent 29.6ms (20.2+9.35) within Sub::Exporter::_collect_collections which was called 233 times, avg 127µs/call:
# 233 times (20.2ms+9.35ms) by Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:756] at line 740, avg 127µs/call | ||||
| 550 | 1631 | 20.3ms | my ($config, $import_args, $class, $into) = @_; | ||
| 551 | |||||
| 552 | my @collections | ||||
| 553 | = map { splice @$import_args, $_, 1 } | ||||
| 554 | grep { exists $config->{collectors}{ $import_args->[$_][0] } } | ||||
| 555 | reverse 0 .. $#$import_args; | ||||
| 556 | |||||
| 557 | unshift @collections, [ INIT => {} ] if $config->{collectors}{INIT}; | ||||
| 558 | |||||
| 559 | my $col = {}; | ||||
| 560 | 233 | 8.86ms | my $builder = _mk_collection_builder($col, \@_); # spent 8.86ms making 233 calls to Sub::Exporter::_mk_collection_builder, avg 38µs/call | ||
| 561 | for my $collection (@collections) { | ||||
| 562 | 3 | 45µs | 3 | 488µs | $builder->($collection) # spent 488µs making 3 calls to Sub::Exporter::__ANON__[Sub/Exporter.pm:544], avg 162µs/call |
| 563 | } | ||||
| 564 | |||||
| 565 | return $col; | ||||
| 566 | } | ||||
| 567 | |||||
| 568 | =head1 SUBROUTINES | ||||
| 569 | |||||
| - - | |||||
| 593 | # spent 2.85ms (130µs+2.72) within Sub::Exporter::setup_exporter which was called 2 times, avg 1.42ms/call:
# once (68µs+1.41ms) by Devel::GlobalDestruction::BEGIN@26 at line 938
# once (61µs+1.31ms) by Moose::Meta::Class::BEGIN@26 at line 36 of Moose/Util.pm | ||||
| 594 | 12 | 123µs | my ($config) = @_; | ||
| 595 | |||||
| 596 | Carp::croak 'into and into_level may not both be supplied to exporter' | ||||
| 597 | if exists $config->{into} and exists $config->{into_level}; | ||||
| 598 | |||||
| 599 | my $as = delete $config->{as} || 'import'; | ||||
| 600 | my $into | ||||
| 601 | = exists $config->{into} ? delete $config->{into} | ||||
| 602 | : exists $config->{into_level} ? caller(delete $config->{into_level}) | ||||
| 603 | : caller(0); | ||||
| 604 | |||||
| 605 | 2 | 2.22ms | my $import = build_exporter($config); # spent 2.22ms making 2 calls to Sub::Exporter::build_exporter, avg 1.11ms/call | ||
| 606 | |||||
| 607 | 2 | 500µs | Sub::Install::reinstall_sub({ # spent 500µs making 2 calls to Sub::Install::__ANON__[Sub/Install.pm:132], avg 250µs/call | ||
| 608 | code => $import, | ||||
| 609 | into => $into, | ||||
| 610 | as => $as, | ||||
| 611 | }); | ||||
| 612 | } | ||||
| 613 | |||||
| 614 | =head2 build_exporter | ||||
| 615 | |||||
| - - | |||||
| 625 | # spent 3.91ms within Sub::Exporter::_key_intersection which was called 45 times, avg 87µs/call:
# 45 times (3.91ms+0s) by Sub::Exporter::_rewrite_build_config at line 681, avg 87µs/call | ||||
| 626 | 135 | 4.09ms | my ($x, $y) = @_; | ||
| 627 | my %seen = map { $_ => 1 } keys %$x; | ||||
| 628 | my @names = grep { $seen{$_} } keys %$y; | ||||
| 629 | } | ||||
| 630 | |||||
| 631 | # Given the config passed to setup_exporter, which contains sugary opt list | ||||
| 632 | # data, rewrite the opt lists into hashes, catch a few kinds of invalid | ||||
| 633 | # configurations, and set up defaults. Since the config is a reference, it's | ||||
| 634 | # rewritten in place. | ||||
| 635 | 1 | 2µs | my %valid_config_key; | ||
| 636 | # spent 64µs within Sub::Exporter::BEGIN@636 which was called:
# once (64µs+0s) by Devel::GlobalDestruction::BEGIN@26 at line 641 | ||||
| 637 | %valid_config_key = | ||||
| 638 | 1 | 69µs | map { $_ => 1 } | ||
| 639 | qw(as collectors installer generator exports groups into into_level), | ||||
| 640 | qw(exporter), # deprecated | ||||
| 641 | 1 | 4.05ms | 1 | 64µs | } # spent 64µs making 1 call to Sub::Exporter::BEGIN@636 |
| 642 | |||||
| 643 | # spent 1.00ms (994µs+10µs) within Sub::Exporter::_assert_collector_names_ok which was called 45 times, avg 22µs/call:
# 45 times (994µs+10µs) by Sub::Exporter::_rewrite_build_config at line 679, avg 22µs/call | ||||
| 644 | 90 | 1.11ms | my ($collectors) = @_; | ||
| 645 | |||||
| 646 | 1 | 31µs | 1 | 10µs | for my $reserved_name (grep { /\A[_A-Z]+\z/ } keys %$collectors) { # spent 10µs making 1 call to Sub::Exporter::CORE:match |
| 647 | Carp::croak "unknown reserved collector name: $reserved_name" | ||||
| 648 | if $reserved_name ne 'INIT'; | ||||
| 649 | } | ||||
| 650 | } | ||||
| 651 | |||||
| 652 | # spent 194ms (9.34+185) within Sub::Exporter::_rewrite_build_config which was called 45 times, avg 4.32ms/call:
# 45 times (9.34ms+185ms) by Sub::Exporter::build_exporter at line 709, avg 4.32ms/call | ||||
| 653 | 585 | 5.92ms | my ($config) = @_; | ||
| 654 | |||||
| 655 | if (my @keys = grep { not exists $valid_config_key{$_} } keys %$config) { | ||||
| 656 | Carp::croak "unknown options (@keys) passed to Sub::Exporter"; | ||||
| 657 | } | ||||
| 658 | |||||
| 659 | Carp::croak q(into and into_level may not both be supplied to exporter) | ||||
| 660 | if exists $config->{into} and exists $config->{into_level}; | ||||
| 661 | |||||
| 662 | # XXX: Remove after deprecation period. | ||||
| 663 | if ($config->{exporter}) { | ||||
| 664 | Carp::cluck "'exporter' argument to build_exporter is deprecated. Use 'installer' instead; the semantics are identical."; | ||||
| 665 | $config->{installer} = delete $config->{exporter}; | ||||
| 666 | } | ||||
| 667 | |||||
| 668 | Carp::croak q(into and into_level may not both be supplied to exporter) | ||||
| 669 | if exists $config->{into} and exists $config->{into_level}; | ||||
| 670 | |||||
| 671 | for (qw(exports collectors)) { | ||||
| 672 | 90 | 2.82ms | 90 | 176ms | $config->{$_} = Data::OptList::mkopt_hash( # spent 176ms making 90 calls to Data::OptList::mkopt_hash, avg 1.96ms/call |
| 673 | $config->{$_}, | ||||
| 674 | $_, | ||||
| 675 | [ 'CODE', 'SCALAR' ], | ||||
| 676 | ); | ||||
| 677 | } | ||||
| 678 | |||||
| 679 | 45 | 1.00ms | _assert_collector_names_ok($config->{collectors}); # spent 1.00ms making 45 calls to Sub::Exporter::_assert_collector_names_ok, avg 22µs/call | ||
| 680 | |||||
| 681 | 45 | 3.91ms | if (my @names = _key_intersection(@$config{qw(exports collectors)})) { # spent 3.91ms making 45 calls to Sub::Exporter::_key_intersection, avg 87µs/call | ||
| 682 | Carp::croak "names (@names) used in both collections and exports"; | ||||
| 683 | } | ||||
| 684 | |||||
| 685 | 45 | 3.65ms | $config->{groups} = Data::OptList::mkopt_hash( # spent 3.65ms making 45 calls to Data::OptList::mkopt_hash, avg 81µs/call | ||
| 686 | $config->{groups}, | ||||
| 687 | 'groups', | ||||
| 688 | [ | ||||
| 689 | 'HASH', # standard opt list | ||||
| 690 | 'ARRAY', # standard opt list | ||||
| 691 | 'CODE', # group generator | ||||
| 692 | 'SCALAR', # name of group generation method | ||||
| 693 | ] | ||||
| 694 | ); | ||||
| 695 | |||||
| 696 | # by default, export nothing | ||||
| 697 | $config->{groups}{default} ||= []; | ||||
| 698 | |||||
| 699 | # by default, build an all-inclusive 'all' group | ||||
| 700 | $config->{groups}{all} ||= [ keys %{ $config->{exports} } ]; | ||||
| 701 | |||||
| 702 | $config->{generator} ||= \&default_generator; | ||||
| 703 | $config->{installer} ||= \&default_installer; | ||||
| 704 | } | ||||
| 705 | |||||
| 706 | # spent 196ms (2.18+194) within Sub::Exporter::build_exporter which was called 45 times, avg 4.37ms/call:
# 33 times (1.59ms+177ms) by MooseX::Types::Base::import at line 91 of MooseX/Types/Base.pm, avg 5.42ms/call
# 7 times (350µs+12.8ms) by Moose::Exporter::_make_exporter at line 127 of Moose/Exporter.pm, avg 1.88ms/call
# 3 times (153µs+1.99ms) by Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:937] at line 937, avg 716µs/call
# 2 times (85µs+2.13ms) by Sub::Exporter::setup_exporter at line 605, avg 1.11ms/call | ||||
| 707 | 180 | 2.14ms | my ($config) = @_; | ||
| 708 | |||||
| 709 | 45 | 194ms | _rewrite_build_config($config); # spent 194ms making 45 calls to Sub::Exporter::_rewrite_build_config, avg 4.32ms/call | ||
| 710 | |||||
| 711 | # spent 1.47s (33.3ms+1.44) within Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:756] which was called 233 times, avg 6.31ms/call:
# 180 times (26.1ms+1.34s) by Moose::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/x86_64-linux/Moose/Exporter.pm:456] at line 455 of Moose/Exporter.pm, avg 7.59ms/call
# 33 times (4.43ms+79.6ms) by MooseX::Types::Base::import at line 115 of MooseX/Types/Base.pm, avg 2.55ms/call
# once (177µs+1.84ms) by MooseX::Params::Validate::BEGIN@12 at line 12 of MooseX/Params/Validate.pm
# once (134µs+1.65ms) by Devel::GlobalDestruction::BEGIN@26 at line 26 of Devel/GlobalDestruction.pm
# once (128µs+1.54ms) by B::Hooks::EndOfScope::BEGIN@16 at line 16 of B/Hooks/EndOfScope.pm
# once (148µs+1.14ms) by Markdent::Role::HTMLStream::BEGIN@15 at line 15 of Markdent/Role/HTMLStream.pm
# once (148µs+1.05ms) by Moose::Exporter::BEGIN@15 at line 15 of Moose/Exporter.pm
# once (132µs+966µs) by namespace::clean::BEGIN@17 at line 17 of namespace/clean.pm
# once (135µs+962µs) by namespace::autoclean::BEGIN@14 at line 14 of namespace/autoclean.pm
# once (181µs+842µs) by Markdent::Simple::Document::BEGIN@12 at line 12 of Markdent/Simple/Document.pm
# once (129µs+748µs) by Moose::Meta::TypeConstraint::DuckType::BEGIN@9 at line 9 of Moose/Meta/TypeConstraint/DuckType.pm
# once (131µs+733µs) by MooseX::Types::Base::BEGIN@13 at line 13 of MooseX/Types/Base.pm
# once (127µs+729µs) by Moose::Meta::Role::Application::ToClass::BEGIN@7 at line 7 of Moose/Meta/Role/Application/ToClass.pm
# once (122µs+733µs) by Moose::Meta::Role::BEGIN@10 at line 10 of Moose/Meta/Role.pm
# once (122µs+732µs) by Class::MOP::Class::BEGIN@16 at line 16 of Class/MOP/Class.pm
# once (127µs+720µs) by Markdent::Parser::BEGIN@13 at line 13 of Markdent/Parser.pm
# once (129µs+705µs) by Moose::Meta::Role::BEGIN@22 at line 22 of Moose/Meta/Role.pm
# once (127µs+705µs) by Markdent::Role::BalancedEvent::BEGIN@11 at line 11 of Markdent/Role/BalancedEvent.pm
# once (152µs+638µs) by Moose::Role::BEGIN@8 at line 8 of Moose/Role.pm
# once (134µs+518µs) by Moose::Meta::Role::Method::Conflicting::BEGIN@7 at line 7 of Moose/Meta/Role/Method/Conflicting.pm
# once (128µs+499µs) by Moose::Util::BEGIN@8 at line 8 of Moose/Util.pm
# once (119µs+470µs) by Moose::Meta::Class::BEGIN@26 at line 26 of Moose/Meta/Class.pm | ||||
| 712 | 2796 | 30.4ms | my ($class) = shift; | ||
| 713 | |||||
| 714 | # XXX: clean this up -- rjbs, 2006-03-16 | ||||
| 715 | my $special = (ref $_[0]) ? shift(@_) : {}; | ||||
| 716 | Carp::croak q(into and into_level may not both be supplied to exporter) | ||||
| 717 | if exists $special->{into} and exists $special->{into_level}; | ||||
| 718 | |||||
| 719 | if ($special->{exporter}) { | ||||
| 720 | Carp::cluck "'exporter' special import argument is deprecated. Use 'installer' instead; the semantics are identical."; | ||||
| 721 | $special->{installer} = delete $special->{exporter}; | ||||
| 722 | } | ||||
| 723 | |||||
| 724 | my $into | ||||
| 725 | = defined $special->{into} ? delete $special->{into} | ||||
| 726 | : defined $special->{into_level} ? caller(delete $special->{into_level}) | ||||
| 727 | : defined $config->{into} ? $config->{into} | ||||
| 728 | : defined $config->{into_level} ? caller($config->{into_level}) | ||||
| 729 | : caller(0); | ||||
| 730 | |||||
| 731 | my $generator = delete $special->{generator} || $config->{generator}; | ||||
| 732 | my $installer = delete $special->{installer} || $config->{installer}; | ||||
| 733 | |||||
| 734 | # this builds a AOA, where the inner arrays are [ name => value_ref ] | ||||
| 735 | 233 | 12.5ms | my $import_args = Data::OptList::mkopt([ @_ ]); # spent 12.5ms making 233 calls to Data::OptList::mkopt, avg 53µs/call | ||
| 736 | |||||
| 737 | # is this right? defaults first or collectors first? -- rjbs, 2006-06-24 | ||||
| 738 | $import_args = [ [ -default => undef ] ] unless @$import_args; | ||||
| 739 | |||||
| 740 | 233 | 29.6ms | my $collection = _collect_collections($config, $import_args, $class, $into); # spent 29.6ms making 233 calls to Sub::Exporter::_collect_collections, avg 127µs/call | ||
| 741 | |||||
| 742 | 233 | 233ms | my $to_import = _expand_groups($class, $config, $import_args, $collection); # spent 233ms making 233 calls to Sub::Exporter::_expand_groups, avg 1.00ms/call | ||
| 743 | |||||
| 744 | # now, finally $import_arg is really the "to do" list | ||||
| 745 | 233 | 1.16s | _do_import( # spent 1.16s making 233 calls to Sub::Exporter::_do_import, avg 4.99ms/call | ||
| 746 | { | ||||
| 747 | class => $class, | ||||
| 748 | col => $collection, | ||||
| 749 | config => $config, | ||||
| 750 | into => $into, | ||||
| 751 | generator => $generator, | ||||
| 752 | installer => $installer, | ||||
| 753 | }, | ||||
| 754 | $to_import, | ||||
| 755 | ); | ||||
| 756 | }; | ||||
| 757 | |||||
| 758 | return $import; | ||||
| 759 | } | ||||
| 760 | |||||
| 761 | # spent 1.16s (146ms+1.02) within Sub::Exporter::_do_import which was called 233 times, avg 4.99ms/call:
# 233 times (146ms+1.02s) by Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:756] at line 745, avg 4.99ms/call | ||||
| 762 | 932 | 9.86ms | my ($arg, $to_import) = @_; | ||
| 763 | |||||
| 764 | my @todo; | ||||
| 765 | |||||
| 766 | for my $pair (@$to_import) { | ||||
| 767 | 10065 | 101ms | my ($name, $import_arg) = @$pair; | ||
| 768 | |||||
| 769 | my ($generator, $as); | ||||
| 770 | |||||
| 771 | 8052 | 30.6ms | 3 | 19µs | if ($import_arg and Params::Util::_CODELIKE($import_arg)) { ## no critic # spent 19µs making 3 calls to Params::Util::_CODELIKE, avg 6µs/call |
| 772 | # This is the case when a group generator has inserted name/code pairs. | ||||
| 773 | $generator = sub { $import_arg }; | ||||
| 774 | $as = $name; | ||||
| 775 | } else { | ||||
| 776 | $import_arg = { $import_arg ? %$import_arg : () }; | ||||
| 777 | |||||
| 778 | Carp::croak qq("$name" is not exported by the $arg->{class} module) | ||||
| 779 | unless exists $arg->{config}{exports}{$name}; | ||||
| 780 | |||||
| 781 | $generator = $arg->{config}{exports}{$name}; | ||||
| 782 | |||||
| 783 | $as = exists $import_arg->{-as} ? (delete $import_arg->{-as}) : $name; | ||||
| 784 | } | ||||
| 785 | |||||
| 786 | 2013 | 224ms | my $code = $arg->{generator}->( # spent 224ms making 2013 calls to Sub::Exporter::default_generator, avg 111µs/call | ||
| 787 | { | ||||
| 788 | class => $arg->{class}, | ||||
| 789 | name => $name, | ||||
| 790 | arg => $import_arg, | ||||
| 791 | col => $arg->{col}, | ||||
| 792 | generator => $generator, | ||||
| 793 | } | ||||
| 794 | ); | ||||
| 795 | |||||
| 796 | push @todo, $as, $code; | ||||
| 797 | } | ||||
| 798 | |||||
| 799 | 233 | 768ms | $arg->{installer}->( # spent 725ms making 180 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:125], avg 4.03ms/call
# spent 42.8ms making 53 calls to Sub::Exporter::default_installer, avg 807µs/call | ||
| 800 | { | ||||
| 801 | class => $arg->{class}, | ||||
| 802 | into => $arg->{into}, | ||||
| 803 | col => $arg->{col}, | ||||
| 804 | }, | ||||
| 805 | \@todo, | ||||
| 806 | ); | ||||
| 807 | } | ||||
| 808 | |||||
| 809 | ## Cute idea, possibly for future use: also supply an "unimport" for: | ||||
| 810 | ## no Module::Whatever qw(arg arg arg); | ||||
| 811 | # sub _unexport { | ||||
| 812 | # my (undef, undef, undef, undef, undef, $as, $into) = @_; | ||||
| 813 | # | ||||
| 814 | # if (ref $as eq 'SCALAR') { | ||||
| 815 | # undef $$as; | ||||
| 816 | # } elsif (ref $as) { | ||||
| 817 | # Carp::croak "invalid reference type for $as: " . ref $as; | ||||
| 818 | # } else { | ||||
| 819 | # no strict 'refs'; | ||||
| 820 | # delete &{$into . '::' . $as}; | ||||
| 821 | # } | ||||
| 822 | # } | ||||
| 823 | |||||
| 824 | =head2 default_generator | ||||
| 825 | |||||
| - - | |||||
| 843 | # spent 224ms (81.1+143) within Sub::Exporter::default_generator which was called 2013 times, avg 111µs/call:
# 2013 times (81.1ms+143ms) by Sub::Exporter::_do_import at line 786, avg 111µs/call | ||||
| 844 | 8039 | 88.6ms | my ($arg) = @_; | ||
| 845 | my ($class, $name, $generator) = @$arg{qw(class name generator)}; | ||||
| 846 | |||||
| 847 | 26 | 579µs | if (not defined $generator) { | ||
| 848 | 13 | 154µs | my $code = $class->can($name) # spent 154µs making 13 calls to UNIVERSAL::can, avg 12µs/call | ||
| 849 | or Carp::croak "can't locate exported subroutine $name via $class"; | ||||
| 850 | return $code; | ||||
| 851 | } | ||||
| 852 | |||||
| 853 | # I considered making this "$class->$generator(" but it seems that | ||||
| 854 | # overloading precedence would turn an overloaded-as-code generator object | ||||
| 855 | # into a string before code. -- rjbs, 2006-06-11 | ||||
| 856 | 4000 | 143ms | return $generator->($class, $name, $arg->{arg}, $arg->{col}) # spent 110ms making 1008 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:329], avg 109µs/call
# spent 10.1ms making 2000 calls to Params::Util::_CODELIKE, avg 5µs/call
# spent 7.09ms making 792 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:259], avg 9µs/call
# spent 5.74ms making 69 calls to MooseX::Types::Base::__ANON__[MooseX/Types/Base.pm:73], avg 83µs/call
# spent 4.79ms making 50 calls to Moose::Exporter::__ANON__[Moose/Exporter.pm:307], avg 96µs/call
# spent 3.03ms making 69 calls to MooseX::Types::Base::__ANON__[MooseX/Types/Base.pm:78], avg 44µs/call
# spent 2.22ms making 3 calls to Sub::Exporter::__ANON__[Sub/Exporter.pm:937], avg 738µs/call
# spent 443µs making 9 calls to MooseX::Types::Base::__ANON__[MooseX/Types/Base.pm:86], avg 49µs/call | ||
| 857 | if Params::Util::_CODELIKE($generator); ## no critic Private | ||||
| 858 | |||||
| 859 | # This "must" be a scalar reference, to a generator method name. | ||||
| 860 | # -- rjbs, 2006-12-05 | ||||
| 861 | return $class->$$generator($name, $arg->{arg}, $arg->{col}); | ||||
| 862 | } | ||||
| 863 | |||||
| 864 | =head2 default_installer | ||||
| 865 | |||||
| - - | |||||
| 882 | # spent 495ms (81.1+414) within Sub::Exporter::default_installer which was called 233 times, avg 2.13ms/call:
# 173 times (70.1ms+359ms) by Moose::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/x86_64-linux/Moose/Exporter.pm:125] at line 117 of Moose/Exporter.pm, avg 2.48ms/call
# 53 times (7.37ms+35.4ms) by Sub::Exporter::_do_import at line 799, avg 807µs/call
# 7 times (3.64ms+20.0ms) by Sub::Exporter::_do_import at line 98 of Moose/Exporter.pm, avg 3.38ms/call | ||||
| 883 | 699 | 22.2ms | my ($arg, $to_export) = @_; | ||
| 884 | |||||
| 885 | 4020 | 21.4ms | for (my $i = 0; $i < @$to_export; $i += 2) { | ||
| 886 | my ($as, $code) = @$to_export[ $i, $i+1 ]; | ||||
| 887 | |||||
| 888 | # Allow as isa ARRAY to push onto an array? | ||||
| 889 | # Allow into isa HASH to install name=>code into hash? | ||||
| 890 | |||||
| 891 | 2010 | 33.9ms | if (ref $as eq 'SCALAR') { | ||
| 892 | $$as = $code; | ||||
| 893 | } elsif (ref $as) { | ||||
| 894 | Carp::croak "invalid reference type for $as: " . ref $as; | ||||
| 895 | } else { | ||||
| 896 | 2010 | 414ms | Sub::Install::reinstall_sub({ # spent 414ms making 2010 calls to Sub::Install::__ANON__[Sub/Install.pm:132], avg 206µs/call | ||
| 897 | code => $code, | ||||
| 898 | into => $arg->{into}, | ||||
| 899 | as => $as | ||||
| 900 | }); | ||||
| 901 | } | ||||
| 902 | } | ||||
| 903 | } | ||||
| 904 | |||||
| 905 | sub default_exporter { | ||||
| 906 | Carp::cluck "default_exporter is deprecated; call default_installer instead; the semantics are identical"; | ||||
| 907 | goto &default_installer; | ||||
| 908 | } | ||||
| 909 | |||||
| 910 | =head1 EXPORTS | ||||
| 911 | |||||
| - - | |||||
| 934 | setup_exporter({ | ||||
| 935 | exports => [ | ||||
| 936 | qw(setup_exporter build_exporter), | ||||
| 937 | 3 | 56µs | 3 | 2.15ms | # spent 2.22ms (68µs+2.15) within Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:937] which was called 3 times, avg 738µs/call:
# 3 times (68µs+2.15ms) by Sub::Exporter::default_generator at line 856, avg 738µs/call # spent 2.15ms making 3 calls to Sub::Exporter::build_exporter, avg 716µs/call |
| 938 | 1 | 46µs | 1 | 1.48ms | ], # spent 1.48ms making 1 call to Sub::Exporter::setup_exporter |
| 939 | groups => { | ||||
| 940 | all => [ qw(setup_exporter build_export) ], | ||||
| 941 | }, | ||||
| 942 | collectors => { -setup => \&_setup }, | ||||
| 943 | }); | ||||
| 944 | |||||
| 945 | # spent 101µs within Sub::Exporter::_setup which was called 3 times, avg 34µs/call:
# 3 times (101µs+0s) by Sub::Exporter::__ANON__[/home/doy/perl5/perlbrew/perls/perl-5.10.1/lib/site_perl/5.10.1/Sub/Exporter.pm:544] at line 539, avg 34µs/call | ||||
| 946 | 6 | 21µs | my ($value, $arg) = @_; | ||
| 947 | |||||
| 948 | 6 | 98µs | if (ref $value eq 'HASH') { | ||
| 949 | push @{ $arg->{import_args} }, [ _import => { -as => 'import', %$value } ]; | ||||
| 950 | return 1; | ||||
| 951 | } elsif (ref $value eq 'ARRAY') { | ||||
| 952 | push @{ $arg->{import_args} }, | ||||
| 953 | [ _import => { -as => 'import', exports => $value } ]; | ||||
| 954 | return 1; | ||||
| 955 | } | ||||
| 956 | return; | ||||
| 957 | } | ||||
| 958 | |||||
| 959 | =head1 COMPARISONS | ||||
| 960 | |||||
| - - | |||||
| 1065 | =over | ||||
| 1066 | |||||
| - - | |||||
| 1101 | 1 | 27µs | "jn8:32"; # <-- magic true value | ||
# spent 311µs within Devel::GlobalDestruction::in_global_destruction which was called 42 times, avg 7µs/call:
# 42 times (311µs+0s) by Class::MOP::Class::DESTROY at line 465 of Class/MOP/Class.pm, avg 7µs/call | |||||
# spent 10µs within Sub::Exporter::CORE:match which was called:
# once (10µs+0s) by Sub::Exporter::_assert_collector_names_ok at line 646 |