← Index
NYTProf Performance Profile   « line view »
For ../prof.pl
  Run on Wed Dec 14 16:10:05 2022
Reported on Wed Dec 14 16:12:57 2022

Filename/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Exporter/Tiny.pm
StatementsExecuted 2319 statements in 10.5ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
59211.81ms1.81msExporter::Tiny::::CORE:regcompExporter::Tiny::CORE:regcomp (opcode)
13111.01ms3.62msExporter::Tiny::::_exporter_permitted_regexpExporter::Tiny::_exporter_permitted_regexp
1311844µs844µsExporter::Tiny::::CORE:sortExporter::Tiny::CORE:sort (opcode)
131312735µs8.42msExporter::Tiny::::importExporter::Tiny::import
4622569µs676µsExporter::Tiny::::_exporter_install_subExporter::Tiny::_exporter_install_sub
4622532µs824µsExporter::Tiny::::_exporter_expand_subExporter::Tiny::_exporter_expand_sub
1311372µs463µsExporter::Tiny::::__ANON__[:52]Exporter::Tiny::__ANON__[:52]
37241282µs282µsExporter::Tiny::::CORE:matchExporter::Tiny::CORE:match (opcode)
1311134µs134µsExporter::Tiny::::mkoptExporter::Tiny::mkopt
111116µs116µsExporter::Tiny::::BEGIN@11Exporter::Tiny::BEGIN@11
11156µs56µsExporter::Tiny::::BEGIN@3Exporter::Tiny::BEGIN@3
131125µs25µsExporter::Tiny::::CORE:qrExporter::Tiny::CORE:qr (opcode)
11117µs29µsExporter::Tiny::::BEGIN@253Exporter::Tiny::BEGIN@253
132214µs14µsExporter::Tiny::::_exporter_validate_optsExporter::Tiny::_exporter_validate_opts
11111µs28µsExporter::Tiny::::BEGIN@137Exporter::Tiny::BEGIN@137
11111µs15µsExporter::Tiny::::BEGIN@396Exporter::Tiny::BEGIN@396
11111µs28µsExporter::Tiny::::BEGIN@5.25Exporter::Tiny::BEGIN@5.25
11111µs11µsExporter::Tiny::::_exporter_expand_tagExporter::Tiny::_exporter_expand_tag
11110µs20µsExporter::Tiny::::BEGIN@4Exporter::Tiny::BEGIN@4
1119µs15µsExporter::Tiny::::BEGIN@190Exporter::Tiny::BEGIN@190
1119µs53µsExporter::Tiny::::BEGIN@5Exporter::Tiny::BEGIN@5
1118µs19µsExporter::Tiny::::BEGIN@69Exporter::Tiny::BEGIN@69
1117µs11µsExporter::Tiny::::BEGIN@217Exporter::Tiny::BEGIN@217
1117µs12µsExporter::Tiny::::BEGIN@347Exporter::Tiny::BEGIN@347
1117µs23µsExporter::Tiny::::BEGIN@382Exporter::Tiny::BEGIN@382
1116µs9µsExporter::Tiny::::BEGIN@236Exporter::Tiny::BEGIN@236
0000s0sExporter::Tiny::::__ANON__[:126]Exporter::Tiny::__ANON__[:126]
0000s0sExporter::Tiny::::__ANON__[:139]Exporter::Tiny::__ANON__[:139]
0000s0sExporter::Tiny::::__ANON__[:145]Exporter::Tiny::__ANON__[:145]
0000s0sExporter::Tiny::::__ANON__[:364]Exporter::Tiny::__ANON__[:364]
0000s0sExporter::Tiny::::__ANON__[:368]Exporter::Tiny::__ANON__[:368]
0000s0sExporter::Tiny::::_carpExporter::Tiny::_carp
0000s0sExporter::Tiny::::_croakExporter::Tiny::_croak
0000s0sExporter::Tiny::::_exporter_expand_regexpExporter::Tiny::_exporter_expand_regexp
0000s0sExporter::Tiny::::_exporter_failExporter::Tiny::_exporter_fail
0000s0sExporter::Tiny::::_exporter_lexical_installerExporter::Tiny::_exporter_lexical_installer
0000s0sExporter::Tiny::::_exporter_merge_optsExporter::Tiny::_exporter_merge_opts
0000s0sExporter::Tiny::::_exporter_uninstall_subExporter::Tiny::_exporter_uninstall_sub
0000s0sExporter::Tiny::::_exporter_validate_unimport_optsExporter::Tiny::_exporter_validate_unimport_opts
0000s0sExporter::Tiny::::mkopt_hashExporter::Tiny::mkopt_hash
0000s0sExporter::Tiny::::unimportExporter::Tiny::unimport
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package Exporter::Tiny;
2
32124µs156µs
# spent 56µs within Exporter::Tiny::BEGIN@3 which was called: # once (56µs+0s) by List::MoreUtils::BEGIN@24 at line 3
use 5.006001;
# spent 56µs making 1 call to Exporter::Tiny::BEGIN@3
4241µs230µs
# spent 20µs (10+10) within Exporter::Tiny::BEGIN@4 which was called: # once (10µs+10µs) by List::MoreUtils::BEGIN@24 at line 4
use strict;
# spent 20µs making 1 call to Exporter::Tiny::BEGIN@4 # spent 10µs making 1 call to strict::import
54202µs4142µs
# spent 28µs (11+17) within Exporter::Tiny::BEGIN@5.25 which was called: # once (11µs+17µs) by List::MoreUtils::BEGIN@24 at line 5 # spent 53µs (9+44) within Exporter::Tiny::BEGIN@5 which was called: # once (9µs+44µs) by List::MoreUtils::BEGIN@24 at line 5
use warnings; no warnings qw(void once uninitialized numeric redefine);
# spent 53µs making 1 call to Exporter::Tiny::BEGIN@5 # spent 44µs making 1 call to warnings::import # spent 28µs making 1 call to Exporter::Tiny::BEGIN@5.25 # spent 17µs making 1 call to warnings::unimport
6
711µsour $AUTHORITY = 'cpan:TOBYINK';
810sour $VERSION = '1.006000';
911µsour @EXPORT_OK = qw< mkopt mkopt_hash _croak _carp >;
10
11
# spent 116µs within Exporter::Tiny::BEGIN@11 which was called: # once (116µs+0s) by List::MoreUtils::BEGIN@24 at line 18
BEGIN {
12 *_HAS_NATIVE_LEXICAL_SUB = ( $] ge '5.037002' )
13 ? sub () { !!1 }
1412µs : sub () { !!0 };
15 *_HAS_MODULE_LEXICAL_SUB = ( $] ge '5.011002' and eval('require Lexical::Sub') )
16 ? sub () { !!1 }
17118µs : sub () { !!0 };
# spent 96µs executing statements in string eval
181463µs1116µs};
# spent 116µs making 1 call to Exporter::Tiny::BEGIN@11
19
20sub _croak ($;@) { require Carp; my $fmt = shift; @_ = sprintf($fmt, @_); goto \&Carp::croak }
21sub _carp ($;@) { require Carp; my $fmt = shift; @_ = sprintf($fmt, @_); goto \&Carp::carp }
22
23my $_process_optlist = sub
24
# spent 463µs (372+91) within Exporter::Tiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Exporter/Tiny.pm:52] which was called 13 times, avg 36µs/call: # 13 times (372µs+91µs) by Exporter::Tiny::import at line 71, avg 36µs/call
{
25132µs my $class = shift;
26138µs my ($global_opts, $opts, $want, $not_want) = @_;
27
281337µs while (@$opts)
29 {
30478µs my $opt = shift @{$opts};
31479µs my ($name, $value) = @$opt;
32
33 ($name =~ m{\A\!(/.+/[msixpodual]*)\z}) ?
34 do {
35 my @not = $class->_exporter_expand_regexp("$1", $value, $global_opts);
36 ++$not_want->{$_->[0]} for @not;
37 } :
38 ($name =~ m{\A\![:-](.+)\z}) ?
39 do {
40 my @not = $class->_exporter_expand_tag("$1", $value, $global_opts);
41 ++$not_want->{$_->[0]} for @not;
42 } :
43 ($name =~ m{\A\!(.+)\z}) ?
4447395µs23591µs (++$not_want->{$1}) :
# spent 80µs making 234 calls to Exporter::Tiny::CORE:match, avg 342ns/call # spent 11µs making 1 call to Exporter::Tiny::_exporter_expand_tag
45 ($name =~ m{\A[:-](.+)\z}) ?
46 push(@$opts, $class->_exporter_expand_tag("$1", $value, $global_opts)) :
47 ($name =~ m{\A/.+/[msixpodual]*\z}) ?
48 push(@$opts, $class->_exporter_expand_regexp($name, $value, $global_opts)) :
49 # else ?
50 push(@$want, $opt);
51 }
5214µs};
53
54sub import
55
# spent 8.42ms (735µs+7.69) within Exporter::Tiny::import which was called 13 times, avg 648µs/call: # once (141µs+2.30ms) by JSON::Schema::Modern::BEGIN@31 at line 31 of JSON/Schema/Modern.pm # once (56µs+986µs) by JSON::Schema::Modern::Document::BEGIN@24 at line 24 of JSON/Schema/Modern/Document.pm # once (65µs+739µs) by JSON::Schema::Modern::Error::BEGIN@20 at line 20 of JSON/Schema/Modern/Error.pm # once (75µs+727µs) by JSON::Schema::Modern::Document::OpenAPI::BEGIN@26 at line 26 of JSON/Schema/Modern/Document/OpenAPI.pm # once (40µs+642µs) by OpenAPI::Modern::BEGIN@31 at line 31 of OpenAPI/Modern.pm # once (34µs+459µs) by File::ShareDir::BEGIN@1 at line 1 of (eval 29)[File/ShareDir.pm:430] # once (40µs+389µs) by JSON::Schema::Modern::Result::BEGIN@18 at line 18 of JSON/Schema/Modern/Result.pm # once (26µs+368µs) by Data::Perl::Role::Collection::Array::BEGIN@9 at line 9 of Data/Perl/Role/Collection/Array.pm # once (28µs+352µs) by JSON::Schema::Modern::Annotation::BEGIN@19 at line 19 of JSON/Schema/Modern/Annotation.pm # once (123µs+205µs) by JSON::Schema::Modern::BEGIN@27 at line 430 of File/ShareDir.pm # once (45µs+227µs) by Eval::TypeTiny::import at line 89 of Eval/TypeTiny.pm # once (33µs+192µs) by Types::Standard::BEGIN@23 at line 23 of Types/Standard.pm # once (29µs+105µs) by Types::Standard::BEGIN@19 at line 19 of Types/Standard.pm
{
56134µs my $class = shift;
571318µs my $global_opts = +{ @_ && ref($_[0]) eq q(HASH) ? %{+shift} : () };
58
59139µs if ( defined $global_opts->{into} and $global_opts->{into} eq '-lexical' ) {
60 $global_opts->{lexical} = 1;
61 delete $global_opts->{into};
62 }
631319µs if ( not defined $global_opts->{into} ) {
64 $global_opts->{into} = caller;
65 }
66
67134µs my @want;
681311µs my %not_want; $global_opts->{not} = \%not_want;
6928481µs230µs
# spent 19µs (8+11) within Exporter::Tiny::BEGIN@69 which was called: # once (8µs+11µs) by List::MoreUtils::BEGIN@24 at line 69
my @args = do { no strict qw(refs); @_ ? @_ : @{"$class\::EXPORT"} };
# spent 19µs making 1 call to Exporter::Tiny::BEGIN@69 # spent 11µs making 1 call to strict::unimport
701322µs13134µs my $opts = mkopt(\@args);
# spent 134µs making 13 calls to Exporter::Tiny::mkopt, avg 10µs/call
711334µs13463µs $class->$_process_optlist($global_opts, $opts, \@want, \%not_want);
# spent 463µs making 13 calls to Exporter::Tiny::__ANON__[Exporter/Tiny.pm:52], avg 36µs/call
72
73 $global_opts->{installer} ||= $class->_exporter_lexical_installer( $global_opts )
74135µs if $global_opts->{lexical};
75
761335µs133.62ms my $permitted = $class->_exporter_permitted_regexp($global_opts);
# spent 3.62ms making 13 calls to Exporter::Tiny::_exporter_permitted_regexp, avg 278µs/call
771338µs13120µs $class->_exporter_validate_opts($global_opts);
# spent 116µs making 8 calls to Type::Library::_exporter_validate_opts, avg 14µs/call # spent 4µs making 5 calls to Exporter::Tiny::_exporter_validate_opts, avg 800ns/call
78
7913103µs for my $wanted (@want) {
804617µs next if $not_want{$wanted->[0]};
81
8246107µs461.92ms my %symbols = $class->_exporter_expand_sub(@$wanted, $global_opts, $permitted);
# spent 1.79ms making 40 calls to Type::Library::_exporter_expand_sub, avg 45µs/call # spent 134µs making 6 calls to Exporter::Tiny::_exporter_expand_sub, avg 22µs/call
83 $class->_exporter_install_sub($_, $wanted->[1], $global_opts, $symbols{$_})
8446196µs461.43ms for keys %symbols;
# spent 1.34ms making 40 calls to Type::Library::_exporter_install_sub, avg 34µs/call # spent 88µs making 6 calls to Exporter::Tiny::_exporter_install_sub, avg 15µs/call
85 }
86}
87
88sub unimport
89{
90 my $class = shift;
91 my $global_opts = +{ @_ && ref($_[0]) eq q(HASH) ? %{+shift} : () };
92 $global_opts->{is_unimport} = 1;
93
94 if ( defined $global_opts->{into} and $global_opts->{into} eq '-lexical' ) {
95 $global_opts->{lexical} = 1;
96 delete $global_opts->{into};
97 }
98 if ( not defined $global_opts->{into} ) {
99 $global_opts->{into} = caller;
100 }
101
102 my @want;
103 my %not_want; $global_opts->{not} = \%not_want;
104 my @args = do { our %TRACKED; @_ ? @_ : keys(%{$TRACKED{$class}{$global_opts->{into}}}) };
105 my $opts = mkopt(\@args);
106 $class->$_process_optlist($global_opts, $opts, \@want, \%not_want);
107
108 my $permitted = $class->_exporter_permitted_regexp($global_opts);
109 $class->_exporter_validate_unimport_opts($global_opts);
110
111 my $expando = $class->can('_exporter_expand_sub');
112 $expando = undef if $expando == \&_exporter_expand_sub;
113
114 for my $wanted (@want)
115 {
116 next if $not_want{$wanted->[0]};
117
118 if ($wanted->[1])
119 {
120 _carp("Passing options to unimport '%s' makes no sense", $wanted->[0])
121 unless (ref($wanted->[1]) eq 'HASH' and not keys %{$wanted->[1]});
122 }
123
124 my %symbols = defined($expando)
125 ? $class->$expando(@$wanted, $global_opts, $permitted)
126 : ($wanted->[0] => sub { "dummy" });
127 $class->_exporter_uninstall_sub($_, $wanted->[1], $global_opts)
128 for keys %symbols;
129 }
130}
131
132# Returns a coderef suitable to be used as a sub installer for lexical imports.
133#
134sub _exporter_lexical_installer {
135 _HAS_NATIVE_LEXICAL_SUB and return sub {
136 my ( $sigilname, $sym ) = @{ $_[1] };
1372426µs245µs
# spent 28µs (11+17) within Exporter::Tiny::BEGIN@137 which was called: # once (11µs+17µs) by List::MoreUtils::BEGIN@24 at line 137
no warnings ( $] ge '5.037002' ? 'experimental::builtin' : () );
# spent 28µs making 1 call to Exporter::Tiny::BEGIN@137 # spent 17µs making 1 call to warnings::unimport
138 builtin::export_lexically( $sigilname, $sym );
139 };
140 _HAS_MODULE_LEXICAL_SUB and return sub {
141 my ( $sigilname, $sym ) = @{ $_[1] };
142 ( $sigilname =~ /^\w/ )
143 ? 'Lexical::Sub'->import( $sigilname, $sym )
144 : 'Lexical::Var'->import( $sigilname, $sym );
145 };
146 _croak( 'Lexical export requires Perl 5.37.2+ for native support, or Perl 5.11.2+ with the Lexical::Sub module' );
147}
148
149# Called once per import/unimport, passed the "global" import options.
150# Expected to validate the options and carp or croak if there are problems.
151# Can also take the opportunity to do other stuff if needed.
152#
1531351µs
# spent 14µs within Exporter::Tiny::_exporter_validate_opts which was called 13 times, avg 1µs/call: # 8 times (10µs+0s) by Type::Library::_exporter_validate_opts at line 36 of Type/Library.pm, avg 1µs/call # 5 times (4µs+0s) by Exporter::Tiny::import at line 77, avg 800ns/call
sub _exporter_validate_opts { 1 }
154sub _exporter_validate_unimport_opts { 1 }
155
156# Called after expanding a tag or regexp to merge the tag's options with
157# any sub-specific options.
158#
159sub _exporter_merge_opts
160{
161 my $class = shift;
162 my ($tag_opts, $global_opts, @stuff) = @_;
163
164 $tag_opts = {} unless ref($tag_opts) eq q(HASH);
165 _croak('Cannot provide an -as option for tags')
166 if exists $tag_opts->{-as} && ref $tag_opts->{-as} ne 'CODE';
167
168 my $optlist = mkopt(\@stuff);
169 for my $export (@$optlist)
170 {
171 next if defined($export->[1]) && ref($export->[1]) ne q(HASH);
172
173 my %sub_opts = ( %{ $export->[1] or {} }, %$tag_opts );
174 $sub_opts{-prefix} = sprintf('%s%s', $tag_opts->{-prefix}, $export->[1]{-prefix})
175 if exists($export->[1]{-prefix}) && exists($tag_opts->{-prefix});
176 $sub_opts{-suffix} = sprintf('%s%s', $export->[1]{-suffix}, $tag_opts->{-suffix})
177 if exists($export->[1]{-suffix}) && exists($tag_opts->{-suffix});
178 $export->[1] = \%sub_opts;
179 }
180 return @$optlist;
181}
182
183# Given a tag name, looks it up in %EXPORT_TAGS and returns the list of
184# associated functions. The default implementation magically handles tags
185# "all" and "default". The default implementation interprets any undefined
186# tags as being global options.
187#
188sub _exporter_expand_tag
189
# spent 11µs within Exporter::Tiny::_exporter_expand_tag which was called: # once (11µs+0s) by Exporter::Tiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Exporter/Tiny.pm:52] at line 44
{
1902186µs221µs
# spent 15µs (9+6) within Exporter::Tiny::BEGIN@190 which was called: # once (9µs+6µs) by List::MoreUtils::BEGIN@24 at line 190
no strict qw(refs);
# spent 15µs making 1 call to Exporter::Tiny::BEGIN@190 # spent 6µs making 1 call to strict::unimport
191
19211µs my $class = shift;
19311µs my ($name, $value, $globals) = @_;
19414µs my $tags = \%{"$class\::EXPORT_TAGS"};
195
196 return $class->_exporter_merge_opts($value, $globals, $tags->{$name}->($class, @_))
19711µs if ref($tags->{$name}) eq q(CODE);
198
199 return $class->_exporter_merge_opts($value, $globals, @{$tags->{$name}})
20010s if exists $tags->{$name};
201
20210s return $class->_exporter_merge_opts($value, $globals, @{"$class\::EXPORT"}, @{"$class\::EXPORT_OK"})
203 if $name eq 'all';
204
20511µs return $class->_exporter_merge_opts($value, $globals, @{"$class\::EXPORT"})
206 if $name eq 'default';
207
20811µs $globals->{$name} = $value || 1;
20914µs return;
210}
211
212# Given a regexp-like string, looks it up in @EXPORT_OK and returns the
213# list of matching functions.
214#
215sub _exporter_expand_regexp
216{
2172116µs215µs
# spent 11µs (7+4) within Exporter::Tiny::BEGIN@217 which was called: # once (7µs+4µs) by List::MoreUtils::BEGIN@24 at line 217
no strict qw(refs);
# spent 11µs making 1 call to Exporter::Tiny::BEGIN@217 # spent 4µs making 1 call to strict::unimport
218 our %TRACKED;
219
220 my $class = shift;
221 my ($name, $value, $globals) = @_;
222 my $compiled = eval("qr$name");
223
224 my @possible = $globals->{is_unimport}
225 ? keys( %{$TRACKED{$class}{$globals->{into}}} )
226 : @{"$class\::EXPORT_OK"};
227
228 $class->_exporter_merge_opts($value, $globals, grep /$compiled/, @possible);
229}
230
231# Helper for _exporter_expand_sub. Returns a regexp matching all subs in
232# the exporter package which are available for export.
233#
234sub _exporter_permitted_regexp
235
# spent 3.62ms (1.01+2.61) within Exporter::Tiny::_exporter_permitted_regexp which was called 13 times, avg 278µs/call: # 13 times (1.01ms+2.61ms) by Exporter::Tiny::import at line 76, avg 278µs/call
{
2362216µs212µs
# spent 9µs (6+3) within Exporter::Tiny::BEGIN@236 which was called: # once (6µs+3µs) by List::MoreUtils::BEGIN@24 at line 236
no strict qw(refs);
# spent 9µs making 1 call to Exporter::Tiny::BEGIN@236 # spent 3µs making 1 call to strict::unimport
237137µs my $class = shift;
238 my $re = join "|", map quotemeta, sort {
239 length($b) <=> length($a) or $a cmp $b
240131.67ms13844µs } @{"$class\::EXPORT"}, @{"$class\::EXPORT_OK"};
# spent 844µs making 13 calls to Exporter::Tiny::CORE:sort, avg 65µs/call
241131.95ms261.77ms qr{^(?:$re)$}ms;
# spent 1.74ms making 13 calls to Exporter::Tiny::CORE:regcomp, avg 134µs/call # spent 25µs making 13 calls to Exporter::Tiny::CORE:qr, avg 2µs/call
242}
243
244# Given a sub name, returns a hash of subs to install (usually just one sub).
245# Keys are sub names, values are coderefs.
246#
247sub _exporter_expand_sub
248
# spent 824µs (532+292) within Exporter::Tiny::_exporter_expand_sub which was called 46 times, avg 18µs/call: # 40 times (440µs+250µs) by Type::Library::_exporter_expand_sub at line 113 of Type/Library.pm, avg 17µs/call # 6 times (92µs+42µs) by Exporter::Tiny::import at line 82, avg 22µs/call
{
249465µs my $class = shift;
2504614µs my ($name, $value, $globals, $permitted) = @_;
251468µs $permitted ||= $class->_exporter_permitted_regexp($globals);
252
2532872µs241µs
# spent 29µs (17+12) within Exporter::Tiny::BEGIN@253 which was called: # once (17µs+12µs) by List::MoreUtils::BEGIN@24 at line 253
no strict qw(refs);
# spent 29µs making 1 call to Exporter::Tiny::BEGIN@253 # spent 12µs making 1 call to strict::unimport
254
2554610µs my $sigil = "&";
2564679µs4628µs if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
# spent 28µs making 46 calls to Exporter::Tiny::CORE:match, avg 609ns/call
257 $sigil = $1;
258 $name = $2;
259 if ($sigil eq '*') {
260 _croak("Cannot export symbols with a * sigil");
261 }
262 }
2634619µs my $sigilname = $sigil eq '&' ? $name : "$sigil$name";
264
26546227µs92138µs if ($sigilname =~ $permitted)
# spent 71µs making 46 calls to Exporter::Tiny::CORE:regcomp, avg 2µs/call # spent 67µs making 46 calls to Exporter::Tiny::CORE:match, avg 1µs/call
266 {
267 my $generatorprefix = {
268 '&' => "_generate_",
269 '$' => "_generateScalar_",
270 '@' => "_generateArray_",
271 '%' => "_generateHash_",
2724690µs }->{$sigil};
273
27446181µs4691µs my $generator = $class->can("$generatorprefix$name");
# spent 91µs making 46 calls to UNIVERSAL::can, avg 2µs/call
275466µs return $sigilname => $class->$generator($sigilname, $value, $globals) if $generator;
276
2774611µs if ($sigil eq '&') {
27846102µs4635µs my $sub = $class->can($name);
# spent 35µs making 46 calls to UNIVERSAL::can, avg 761ns/call
27946177µs return $sigilname => $sub if $sub;
280 }
281 else {
282 # Could do this more cleverly, but this works.
283 my $evalled = eval "\\${sigil}${class}::${name}";
284 return $sigilname => $evalled if $evalled;
285 }
286 }
287
288 $class->_exporter_fail(@_);
289}
290
291# Called by _exporter_expand_sub if it is unable to generate a key-value
292# pair for a sub.
293#
294sub _exporter_fail
295{
296 my $class = shift;
297 my ($name, $value, $globals) = @_;
298 return if $globals->{is_unimport};
299 _croak("Could not find sub '%s' exported by %s", $name, $class);
300}
301
302# Actually performs the installation of the sub into the target package. This
303# also handles renaming the sub.
304#
305sub _exporter_install_sub
306
# spent 676µs (569+107) within Exporter::Tiny::_exporter_install_sub which was called 46 times, avg 15µs/call: # 40 times (483µs+105µs) by Type::Library::_exporter_install_sub at line 154 of Type/Library.pm, avg 15µs/call # 6 times (86µs+2µs) by Exporter::Tiny::import at line 84, avg 15µs/call
{
3074614µs my $class = shift;
3084618µs my ($name, $value, $globals, $sym) = @_;
3094619µs my $value_hash = ( ref($value) eq 'HASH' ) ? $value : {};
310
3114612µs my $into = $globals->{into};
3124615µs my $installer = $globals->{installer} || $globals->{exporter};
313
314 $name =
315 ref $globals->{as} ? $globals->{as}->($name) :
316 ref $value_hash->{-as} ? $value_hash->{-as}->($name) :
317 exists $value_hash->{-as} ? $value_hash->{-as} :
3184618µs $name;
319
3204610µs return unless defined $name;
321
322464µs my $sigil = "&";
3234619µs unless (ref($name)) {
32446190µs46107µs if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
# spent 107µs making 46 calls to Exporter::Tiny::CORE:match, avg 2µs/call
325 $sigil = $1;
326 $name = $2;
327 if ($sigil eq '*') {
328 _croak("Cannot export symbols with a * sigil");
329 }
330 }
3314656µs my ($prefix) = grep defined, $value_hash->{-prefix}, $globals->{prefix}, q();
3324622µs my ($suffix) = grep defined, $value_hash->{-suffix}, $globals->{suffix}, q();
3334623µs $name = "$prefix$name$suffix";
334 }
335
3364613µs my $sigilname = $sigil eq '&' ? $name : ( $sigil . $name );
337
338# if ({qw/$ SCALAR @ ARRAY % HASH & CODE/}->{$sigil} ne ref($sym)) {
339# warn $sym;
340# warn $sigilname;
341# _croak("Reference type %s does not match sigil %s", ref($sym), $sigil);
342# }
343
344469µs return ($$name = $sym) if ref($name) eq q(SCALAR);
345467µs return ($into->{$sigilname} = $sym) if ref($into) eq q(HASH);
346
3472178µs217µs
# spent 12µs (7+5) within Exporter::Tiny::BEGIN@347 which was called: # once (7µs+5µs) by List::MoreUtils::BEGIN@24 at line 347
no strict qw(refs);
# spent 12µs making 1 call to Exporter::Tiny::BEGIN@347 # spent 5µs making 1 call to strict::unimport
348 our %TRACKED;
349
3504662µs if ( ref($sym) eq 'CODE'
351 and ref($into) ? exists($into->{$name}) : exists(&{"$into\::$name"})
352 and $sym != ( ref($into) ? $into->{$name} : \&{"$into\::$name"} ) )
353 {
354 my ($level) = grep defined, $value_hash->{-replace}, $globals->{replace}, q(0);
355 my $action = {
356 carp => \&_carp,
357 0 => \&_carp,
358 '' => \&_carp,
359 warn => \&_carp,
360 nonfatal => \&_carp,
361 croak => \&_croak,
362 fatal => \&_croak,
363 die => \&_croak,
364 }->{$level} || sub {};
365
366 # Don't complain about double-installing the same sub. This isn't ideal
367 # because the same named sub might be generated in two different ways.
368 $action = sub {} if $TRACKED{$class}{$into}{$sigilname};
369
370 $action->(
371 $action == \&_croak
372 ? "Refusing to overwrite existing sub '%s' with sub '%s' exported by %s"
373 : "Overwriting existing sub '%s' with sub '%s' exported by %s",
374 ref($into) ? $name : "$into\::$name",
375 $_[0],
376 $class,
377 );
378 }
379
3804629µs $TRACKED{$class}{$into}{$sigilname} = $sym;
381
3822134µs239µs
# spent 23µs (7+16) within Exporter::Tiny::BEGIN@382 which was called: # once (7µs+16µs) by List::MoreUtils::BEGIN@24 at line 382
no warnings qw(prototype);
# spent 23µs making 1 call to Exporter::Tiny::BEGIN@382 # spent 16µs making 1 call to warnings::unimport
383 $installer
384 ? $installer->($globals, [$sigilname, $sym])
38546168µs : (*{"$into\::$name"} = $sym);
386}
387
388sub _exporter_uninstall_sub
389{
390 our %TRACKED;
391 my $class = shift;
392 my ($name, $value, $globals, $sym) = @_;
393 my $into = $globals->{into};
394 ref $into and return;
395
3962448µs219µs
# spent 15µs (11+4) within Exporter::Tiny::BEGIN@396 which was called: # once (11µs+4µs) by List::MoreUtils::BEGIN@24 at line 396
no strict qw(refs);
# spent 15µs making 1 call to Exporter::Tiny::BEGIN@396 # spent 4µs making 1 call to strict::unimport
397
398 my $sigil = "&";
399 if ($name =~ /\A([&\$\%\@\*])(.+)\z/) {
400 $sigil = $1;
401 $name = $2;
402 if ($sigil eq '*') {
403 _croak("Cannot export symbols with a * sigil");
404 }
405 }
406 my $sigilname = $sigil eq '&' ? $name : "$sigil$name";
407
408 if ($sigil ne '&') {
409 _croak("Unimporting non-code symbols not supported yet");
410 }
411
412 # Cowardly refuse to uninstall a sub that differs from the one
413 # we installed!
414 my $our_coderef = $TRACKED{$class}{$into}{$name};
415 my $cur_coderef = exists(&{"$into\::$name"}) ? \&{"$into\::$name"} : -1;
416 return unless $our_coderef == $cur_coderef;
417
418 my $stash = \%{"$into\::"};
419 my $old = delete $stash->{$name};
420 my $full_name = join('::', $into, $name);
421 foreach my $type (qw(SCALAR HASH ARRAY IO)) # everything but the CODE
422 {
423 next unless defined(*{$old}{$type});
424 *$full_name = *{$old}{$type};
425 }
426
427 delete $TRACKED{$class}{$into}{$name};
428}
429
430sub mkopt
431
# spent 134µs within Exporter::Tiny::mkopt which was called 13 times, avg 10µs/call: # 13 times (134µs+0s) by Exporter::Tiny::import at line 70, avg 10µs/call
{
432137µs my $in = shift or return [];
433133µs my @out;
434
4351310µs $in = [map(($_ => ref($in->{$_}) ? $in->{$_} : ()), sort keys %$in)]
436 if ref($in) eq q(HASH);
437
4381328µs for (my $i = 0; $i < @$in; $i++)
439 {
4404712µs my $k = $in->[$i];
441472µs my $v;
442
4434721µs ($i == $#$in) ? ($v = undef) :
444 !defined($in->[$i+1]) ? (++$i, ($v = undef)) :
445 !ref($in->[$i+1]) ? ($v = undef) :
446 ($v = $in->[++$i]);
447
4484726µs push @out, [ $k => $v ];
449 }
450
4511348µs \@out;
452}
453
454sub mkopt_hash
455{
456 my $in = shift or return;
457 my %out = map +($_->[0] => $_->[1]), @{ mkopt($in) };
458 \%out;
459}
460
46117µs1;
462
463__END__
 
# spent 282µs within Exporter::Tiny::CORE:match which was called 372 times, avg 758ns/call: # 234 times (80µs+0s) by Exporter::Tiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Exporter/Tiny.pm:52] at line 44, avg 342ns/call # 46 times (107µs+0s) by Exporter::Tiny::_exporter_install_sub at line 324, avg 2µs/call # 46 times (67µs+0s) by Exporter::Tiny::_exporter_expand_sub at line 265, avg 1µs/call # 46 times (28µs+0s) by Exporter::Tiny::_exporter_expand_sub at line 256, avg 609ns/call
sub Exporter::Tiny::CORE:match; # opcode
# spent 25µs within Exporter::Tiny::CORE:qr which was called 13 times, avg 2µs/call: # 13 times (25µs+0s) by Exporter::Tiny::_exporter_permitted_regexp at line 241, avg 2µs/call
sub Exporter::Tiny::CORE:qr; # opcode
# spent 1.81ms within Exporter::Tiny::CORE:regcomp which was called 59 times, avg 31µs/call: # 46 times (71µs+0s) by Exporter::Tiny::_exporter_expand_sub at line 265, avg 2µs/call # 13 times (1.74ms+0s) by Exporter::Tiny::_exporter_permitted_regexp at line 241, avg 134µs/call
sub Exporter::Tiny::CORE:regcomp; # opcode
# spent 844µs within Exporter::Tiny::CORE:sort which was called 13 times, avg 65µs/call: # 13 times (844µs+0s) by Exporter::Tiny::_exporter_permitted_regexp at line 240, avg 65µs/call
sub Exporter::Tiny::CORE:sort; # opcode