Filename | /usr/local/share/perl/5.18.2/App/Cmd/Setup.pm |
Statements | Executed 51 statements in 2.48ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.43ms | 37.8ms | BEGIN@72 | App::Cmd::Setup::
1 | 1 | 1 | 1.19ms | 1.26ms | BEGIN@73 | App::Cmd::Setup::
1 | 1 | 1 | 654µs | 970µs | BEGIN@77 | App::Cmd::Setup::
1 | 1 | 1 | 406µs | 454µs | BEGIN@74 | App::Cmd::Setup::
1 | 1 | 1 | 42µs | 400µs | _make_app_class | App::Cmd::Setup::
1 | 1 | 1 | 20µs | 33µs | BEGIN@1 | PONAPI::CLI::
1 | 1 | 1 | 8µs | 8µs | _make_x_isa_y | App::Cmd::Setup::
1 | 1 | 1 | 8µs | 274µs | BEGIN@82 | App::Cmd::Setup::
1 | 1 | 1 | 8µs | 18µs | BEGIN@167 | App::Cmd::Setup::
1 | 1 | 1 | 8µs | 16µs | BEGIN@80 | App::Cmd::Setup::
1 | 1 | 1 | 5µs | 8µs | BEGIN@2 | PONAPI::CLI::
4 | 2 | 1 | 5µs | 5µs | __ANON__[:114] | App::Cmd::Setup::
1 | 1 | 1 | 3µs | 3µs | BEGIN@75 | App::Cmd::Setup::
3 | 1 | 1 | 3µs | 3µs | __ANON__[:142] | App::Cmd::Setup::
1 | 1 | 1 | 2µs | 2µs | BEGIN@76 | App::Cmd::Setup::
1 | 1 | 1 | 2µs | 2µs | import | App::Cmd::Setup::
1 | 1 | 1 | 1µs | 1µs | _command_base_class | App::Cmd::Setup::
1 | 1 | 1 | 800ns | 800ns | _app_base_class | App::Cmd::Setup::
0 | 0 | 0 | 0s | 0s | _make_command_class | App::Cmd::Setup::
0 | 0 | 0 | 0s | 0s | _make_plugin_class | App::Cmd::Setup::
0 | 0 | 0 | 0s | 0s | _plugin_base_class | App::Cmd::Setup::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | 2 | 20µs | 2 | 46µs | # spent 33µs (20+13) within PONAPI::CLI::BEGIN@1 which was called:
# once (20µs+13µs) by PONAPI::CLI::BEGIN@5 at line 1 # spent 33µs making 1 call to PONAPI::CLI::BEGIN@1
# spent 13µs making 1 call to strict::import |
2 | 2 | 53µs | 2 | 11µs | # spent 8µs (5+3) within PONAPI::CLI::BEGIN@2 which was called:
# once (5µs+3µs) by PONAPI::CLI::BEGIN@5 at line 2 # spent 8µs making 1 call to PONAPI::CLI::BEGIN@2
# spent 3µs making 1 call to warnings::import |
3 | package App::Cmd::Setup; | ||||
4 | 1 | 500ns | $App::Cmd::Setup::VERSION = '0.330'; | ||
5 | # ABSTRACT: helper for setting up App::Cmd classes | ||||
6 | |||||
7 | #pod =head1 OVERVIEW | ||||
8 | #pod | ||||
9 | #pod App::Cmd::Setup is a helper library, used to set up base classes that will be | ||||
10 | #pod used as part of an App::Cmd program. For the most part you should refer to | ||||
11 | #pod L<the tutorial|App::Cmd::Tutorial> for how you should use this library. | ||||
12 | #pod | ||||
13 | #pod This class is useful in three scenarios: | ||||
14 | #pod | ||||
15 | #pod =begin :list | ||||
16 | #pod | ||||
17 | #pod = when writing your App::Cmd subclass | ||||
18 | #pod | ||||
19 | #pod Instead of writing: | ||||
20 | #pod | ||||
21 | #pod package MyApp; | ||||
22 | #pod use base 'App::Cmd'; | ||||
23 | #pod | ||||
24 | #pod ...you can write: | ||||
25 | #pod | ||||
26 | #pod package MyApp; | ||||
27 | #pod use App::Cmd::Setup -app; | ||||
28 | #pod | ||||
29 | #pod The benefits of doing this are mostly minor, and relate to sanity-checking your | ||||
30 | #pod class. The significant benefit is that this form allows you to specify | ||||
31 | #pod plugins, as in: | ||||
32 | #pod | ||||
33 | #pod package MyApp; | ||||
34 | #pod use App::Cmd::Setup -app => { plugins => [ 'Prompt' ] }; | ||||
35 | #pod | ||||
36 | #pod Plugins are described in L<App::Cmd::Tutorial> and L<App::Cmd::Plugin>. | ||||
37 | #pod | ||||
38 | #pod = when writing abstract base classes for commands | ||||
39 | #pod | ||||
40 | #pod That is: when you write a subclass of L<App::Cmd::Command> that is intended for | ||||
41 | #pod other commands to use as their base class, you should use App::Cmd::Setup. For | ||||
42 | #pod example, if you want all the commands in MyApp to inherit from MyApp::Command, | ||||
43 | #pod you may want to write that package like this: | ||||
44 | #pod | ||||
45 | #pod package MyApp::Command; | ||||
46 | #pod use App::Cmd::Setup -command; | ||||
47 | #pod | ||||
48 | #pod Do not confuse this with the way you will write specific commands: | ||||
49 | #pod | ||||
50 | #pod package MyApp::Command::mycmd; | ||||
51 | #pod use MyApp -command; | ||||
52 | #pod | ||||
53 | #pod Again, this form mostly performs some validation and setup behind the scenes | ||||
54 | #pod for you. You can use C<L<base>> if you prefer. | ||||
55 | #pod | ||||
56 | #pod = when writing App::Cmd plugins | ||||
57 | #pod | ||||
58 | #pod L<App::Cmd::Plugin> is a mechanism that allows an App::Cmd class to inject code | ||||
59 | #pod into all its command classes, providing them with utility routines. | ||||
60 | #pod | ||||
61 | #pod To write a plugin, you must use App::Cmd::Setup. As seen above, you must also | ||||
62 | #pod use App::Cmd::Setup to set up your App::Cmd subclass if you wish to consume | ||||
63 | #pod plugins. | ||||
64 | #pod | ||||
65 | #pod For more information on writing plugins, see L<App::Cmd::Manual> and | ||||
66 | #pod L<App::Cmd::Plugin>. | ||||
67 | #pod | ||||
68 | #pod =end :list | ||||
69 | #pod | ||||
70 | #pod =cut | ||||
71 | |||||
72 | 2 | 455µs | 1 | 37.8ms | # spent 37.8ms (2.43+35.4) within App::Cmd::Setup::BEGIN@72 which was called:
# once (2.43ms+35.4ms) by PONAPI::CLI::BEGIN@5 at line 72 # spent 37.8ms making 1 call to App::Cmd::Setup::BEGIN@72 |
73 | 2 | 495µs | 1 | 1.26ms | # spent 1.26ms (1.19+65µs) within App::Cmd::Setup::BEGIN@73 which was called:
# once (1.19ms+65µs) by PONAPI::CLI::BEGIN@5 at line 73 # spent 1.26ms making 1 call to App::Cmd::Setup::BEGIN@73 |
74 | 2 | 355µs | 1 | 454µs | # spent 454µs (406+48) within App::Cmd::Setup::BEGIN@74 which was called:
# once (406µs+48µs) by PONAPI::CLI::BEGIN@5 at line 74 # spent 454µs making 1 call to App::Cmd::Setup::BEGIN@74 |
75 | 2 | 15µs | 1 | 3µs | # spent 3µs within App::Cmd::Setup::BEGIN@75 which was called:
# once (3µs+0s) by PONAPI::CLI::BEGIN@5 at line 75 # spent 3µs making 1 call to App::Cmd::Setup::BEGIN@75 |
76 | 2 | 14µs | 1 | 2µs | # spent 2µs within App::Cmd::Setup::BEGIN@76 which was called:
# once (2µs+0s) by PONAPI::CLI::BEGIN@5 at line 76 # spent 2µs making 1 call to App::Cmd::Setup::BEGIN@76 |
77 | 2 | 380µs | 1 | 970µs | # spent 970µs (654+315) within App::Cmd::Setup::BEGIN@77 which was called:
# once (654µs+315µs) by PONAPI::CLI::BEGIN@5 at line 77 # spent 970µs making 1 call to App::Cmd::Setup::BEGIN@77 |
78 | |||||
79 | # 0.06 is needed for load_optional_class | ||||
80 | 3 | 51µs | 2 | 23µs | # spent 16µs (8+8) within App::Cmd::Setup::BEGIN@80 which was called:
# once (8µs+8µs) by PONAPI::CLI::BEGIN@5 at line 80 # spent 16µs making 1 call to App::Cmd::Setup::BEGIN@80
# spent 8µs making 1 call to UNIVERSAL::VERSION |
81 | |||||
82 | 1 | 6µs | 1 | 266µs | # spent 274µs (8+266) within App::Cmd::Setup::BEGIN@82 which was called:
# once (8µs+266µs) by PONAPI::CLI::BEGIN@5 at line 90 # spent 266µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:337] |
83 | -as => '_import', | ||||
84 | exports => [ qw(foo) ], | ||||
85 | collectors => [ | ||||
86 | -app => \'_make_app_class', | ||||
87 | -command => \'_make_command_class', | ||||
88 | -plugin => \'_make_plugin_class', | ||||
89 | ], | ||||
90 | 1 | 392µs | 1 | 274µs | }; # spent 274µs making 1 call to App::Cmd::Setup::BEGIN@82 |
91 | |||||
92 | # spent 2µs within App::Cmd::Setup::import which was called:
# once (2µs+0s) by PONAPI::CLI::BEGIN@5 at line 5 of lib/PONAPI/CLI.pm | ||||
93 | 1 | 6µs | 1 | 470µs | goto &_import; # spent 470µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:337] |
94 | } | ||||
95 | |||||
96 | 1 | 2µs | # spent 800ns within App::Cmd::Setup::_app_base_class which was called:
# once (800ns+0s) by App::Cmd::Setup::_make_app_class at line 109 | ||
97 | |||||
98 | # spent 400µs (42+358) within App::Cmd::Setup::_make_app_class which was called:
# once (42µs+358µs) by Sub::Exporter::__ANON__[/usr/local/share/perl/5.18.2/Sub/Exporter.pm:159] at line 151 of Sub/Exporter.pm | ||||
99 | 1 | 400ns | my ($self, $val, $data) = @_; | ||
100 | 1 | 300ns | my $into = $data->{into}; | ||
101 | |||||
102 | 1 | 300ns | $val ||= {}; | ||
103 | Carp::confess "invalid argument to -app setup" | ||||
104 | 1 | 700ns | if grep { $_ ne 'plugins' } keys %$val; | ||
105 | |||||
106 | 1 | 8µs | 1 | 2µs | Carp::confess "app setup requested on App::Cmd subclass $into" # spent 2µs making 1 call to UNIVERSAL::isa |
107 | if $into->isa('App::Cmd'); | ||||
108 | |||||
109 | 1 | 2µs | 2 | 9µs | $self->_make_x_isa_y($into, $self->_app_base_class); # spent 8µs making 1 call to App::Cmd::Setup::_make_x_isa_y
# spent 800ns making 1 call to App::Cmd::Setup::_app_base_class |
110 | |||||
111 | 1 | 6µs | 2 | 287µs | if ( ! Class::Load::load_optional_class( $into->_default_command_base ) ) { # spent 284µs making 1 call to Class::Load::load_optional_class
# spent 2µs making 1 call to App::Cmd::_default_command_base |
112 | 1 | 2µs | 1 | 1µs | my $base = $self->_command_base_class; # spent 1µs making 1 call to App::Cmd::Setup::_command_base_class |
113 | Sub::Install::install_sub({ | ||||
114 | 4 | 10µs | # spent 5µs within App::Cmd::Setup::__ANON__[/usr/local/share/perl/5.18.2/App/Cmd/Setup.pm:114] which was called 4 times, avg 1µs/call:
# 3 times (4µs+0s) by App::Cmd::_setup_command at line 34 of App/Cmd.pm, avg 1µs/call
# once (800ns+0s) by App::Cmd::plugin_search_path at line 497 of App/Cmd.pm | ||
115 | 1 | 4µs | 1 | 36µs | into => $into, # spent 36µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:118] |
116 | as => '_default_command_base', | ||||
117 | }); | ||||
118 | } | ||||
119 | |||||
120 | # TODO Check this is right. -- kentnl, 2010-12 | ||||
121 | # | ||||
122 | # my $want_plugin_base = $self->_plugin_base_class; | ||||
123 | 1 | 300ns | my $want_plugin_base = 'App::Cmd::Plugin'; | ||
124 | |||||
125 | 1 | 100ns | my @plugins; | ||
126 | 1 | 1µs | for my $plugin (@{ $val->{plugins} || [] }) { | ||
127 | $plugin = String::RewritePrefix->rewrite( | ||||
128 | { | ||||
129 | '' => 'App::Cmd::Plugin::', | ||||
130 | '=' => '' | ||||
131 | }, | ||||
132 | $plugin, | ||||
133 | ); | ||||
134 | Class::Load::load_class( $plugin ); | ||||
135 | unless( $plugin->isa( $want_plugin_base ) ){ | ||||
136 | die "$plugin is not a " . $want_plugin_base; | ||||
137 | } | ||||
138 | push @plugins, $plugin; | ||||
139 | } | ||||
140 | |||||
141 | Sub::Install::install_sub({ | ||||
142 | 3 | 8µs | # spent 3µs within App::Cmd::Setup::__ANON__[/usr/local/share/perl/5.18.2/App/Cmd/Setup.pm:142] which was called 3 times, avg 967ns/call:
# 3 times (3µs+0s) by App::Cmd::_setup_command at line 42 of App/Cmd.pm, avg 967ns/call | ||
143 | 1 | 3µs | 1 | 23µs | into => $into, # spent 23µs making 1 call to Sub::Install::__ANON__[Sub/Install.pm:118] |
144 | as => '_plugin_plugins', | ||||
145 | }); | ||||
146 | |||||
147 | 1 | 6µs | return 1; | ||
148 | } | ||||
149 | |||||
150 | 1 | 5µs | # spent 1µs within App::Cmd::Setup::_command_base_class which was called:
# once (1µs+0s) by App::Cmd::Setup::_make_app_class at line 112 | ||
151 | |||||
152 | sub _make_command_class { | ||||
153 | my ($self, $val, $data) = @_; | ||||
154 | my $into = $data->{into}; | ||||
155 | |||||
156 | Carp::confess "command setup requested on App::Cmd::Command subclass $into" | ||||
157 | if $into->isa('App::Cmd::Command'); | ||||
158 | |||||
159 | $self->_make_x_isa_y($into, $self->_command_base_class); | ||||
160 | |||||
161 | return 1; | ||||
162 | } | ||||
163 | |||||
164 | # spent 8µs within App::Cmd::Setup::_make_x_isa_y which was called:
# once (8µs+0s) by App::Cmd::Setup::_make_app_class at line 109 | ||||
165 | 1 | 600ns | my ($self, $x, $y) = @_; | ||
166 | |||||
167 | 2 | 164µs | 2 | 29µs | # spent 18µs (8+10) within App::Cmd::Setup::BEGIN@167 which was called:
# once (8µs+10µs) by PONAPI::CLI::BEGIN@5 at line 167 # spent 18µs making 1 call to App::Cmd::Setup::BEGIN@167
# spent 10µs making 1 call to strict::unimport |
168 | 1 | 10µs | push @{"$x\::ISA"}, $y; | ||
169 | } | ||||
170 | |||||
171 | sub _plugin_base_class { 'App::Cmd::Plugin' } | ||||
172 | sub _make_plugin_class { | ||||
173 | my ($self, $val, $data) = @_; | ||||
174 | my $into = $data->{into}; | ||||
175 | |||||
176 | Carp::confess "plugin setup requested on App::Cmd::Plugin subclass $into" | ||||
177 | if $into->isa('App::Cmd::Plugin'); | ||||
178 | |||||
179 | Carp::confess "plugin setup requires plugin configuration" unless $val; | ||||
180 | |||||
181 | $self->_make_x_isa_y($into, $self->_plugin_base_class); | ||||
182 | |||||
183 | # In this special case, exporting everything by default is the sensible thing | ||||
184 | # to do. -- rjbs, 2008-03-31 | ||||
185 | $val->{groups} = [ default => [ -all ] ] unless $val->{groups}; | ||||
186 | |||||
187 | my @exports; | ||||
188 | for my $pair (@{ Data::OptList::mkopt($val->{exports}) }) { | ||||
189 | push @exports, $pair->[0], ($pair->[1] || \'_faux_curried_method'); | ||||
190 | } | ||||
191 | |||||
192 | $val->{exports} = \@exports; | ||||
193 | |||||
194 | Sub::Exporter::setup_exporter({ | ||||
195 | %$val, | ||||
196 | into => $into, | ||||
197 | as => 'import_from_plugin', | ||||
198 | }); | ||||
199 | |||||
200 | return 1; | ||||
201 | } | ||||
202 | |||||
203 | 1 | 3µs | 1; | ||
204 | |||||
205 | __END__ |