Profile of App/Cmd/Setup.pm

← Index
NYTProf Performance Profile «line view»
For script/ponapi
Run on Wed Feb 10 15:51:26 2016
Reported on Thu Feb 11 09:43:08 2016

Filename | /usr/local/share/perl/5.18.2/App/Cmd/Setup.pm
Statements | Executed 51 statements in 2.48ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 2.43ms | 37.8ms | App::Cmd::Setup::::BEGIN@72App::Cmd::Setup::BEGIN@72
1 | 1 | 1 | 1.19ms | 1.26ms | App::Cmd::Setup::::BEGIN@73App::Cmd::Setup::BEGIN@73
1 | 1 | 1 | 654µs | 970µs | App::Cmd::Setup::::BEGIN@77App::Cmd::Setup::BEGIN@77
1 | 1 | 1 | 406µs | 454µs | App::Cmd::Setup::::BEGIN@74App::Cmd::Setup::BEGIN@74
1 | 1 | 1 | 42µs | 400µs | App::Cmd::Setup::::_make_app_classApp::Cmd::Setup::_make_app_class
1 | 1 | 1 | 20µs | 33µs | PONAPI::CLI::::BEGIN@1 PONAPI::CLI::BEGIN@1
1 | 1 | 1 | 8µs | 8µs | App::Cmd::Setup::::_make_x_isa_yApp::Cmd::Setup::_make_x_isa_y
1 | 1 | 1 | 8µs | 274µs | App::Cmd::Setup::::BEGIN@82App::Cmd::Setup::BEGIN@82
1 | 1 | 1 | 8µs | 18µs | App::Cmd::Setup::::BEGIN@167App::Cmd::Setup::BEGIN@167
1 | 1 | 1 | 8µs | 16µs | App::Cmd::Setup::::BEGIN@80App::Cmd::Setup::BEGIN@80
1 | 1 | 1 | 5µs | 8µs | PONAPI::CLI::::BEGIN@2 PONAPI::CLI::BEGIN@2
4 | 2 | 1 | 5µs | 5µs | App::Cmd::Setup::::__ANON__[:114]App::Cmd::Setup::__ANON__[:114]
1 | 1 | 1 | 3µs | 3µs | App::Cmd::Setup::::BEGIN@75App::Cmd::Setup::BEGIN@75
3 | 1 | 1 | 3µs | 3µs | App::Cmd::Setup::::__ANON__[:142]App::Cmd::Setup::__ANON__[:142]
1 | 1 | 1 | 2µs | 2µs | App::Cmd::Setup::::BEGIN@76App::Cmd::Setup::BEGIN@76
1 | 1 | 1 | 2µs | 2µs | App::Cmd::Setup::::importApp::Cmd::Setup::import
1 | 1 | 1 | 1µs | 1µs | App::Cmd::Setup::::_command_base_classApp::Cmd::Setup::_command_base_class
1 | 1 | 1 | 800ns | 800ns | App::Cmd::Setup::::_app_base_classApp::Cmd::Setup::_app_base_class
0 | 0 | 0 | 0s | 0s | App::Cmd::Setup::::_make_command_classApp::Cmd::Setup::_make_command_class
0 | 0 | 0 | 0s | 0s | App::Cmd::Setup::::_make_plugin_classApp::Cmd::Setup::_make_plugin_class
0 | 0 | 0 | 0s | 0s | App::Cmd::Setup::::_plugin_base_classApp::Cmd::Setup::_plugin_base_class

Call graph for these subroutines as a Graphviz dot language file.

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 use strict; # 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 use warnings; # 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 use App::Cmd (); # 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 use App::Cmd::Command (); # 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 use App::Cmd::Plugin (); # 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 use Carp (); # 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 use Data::OptList (); # 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 use String::RewritePrefix (); # 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 use Class::Load 0.06 qw(); # 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 use Sub::Exporter -setup => { # 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 sub import {
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 sub _app_base_class { 'App::Cmd' }
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 sub _make_app_class {
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 code => sub { $base },
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 code => sub { @plugins },
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 sub _command_base_class { 'App::Cmd::Command' }
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 sub _make_x_isa_y {
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 no strict 'refs'; # 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__