Profile of CPAN/Meta.pm

← Index
NYTProf Performance Profile «line view»
For test.pl
Run on Mon Apr 5 14:31:27 2021
Reported on Mon Apr 5 14:31:40 2021

Filename | /home/leont/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/CPAN/Meta.pm
Statements | Executed 74 statements in 1.41ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 3.88ms | 7.00ms | CPAN::Meta::::BEGIN@59CPAN::Meta::BEGIN@59
1 | 1 | 1 | 181µs | 3.79ms | CPAN::Meta::::BEGIN@57CPAN::Meta::BEGIN@57
1 | 1 | 1 | 16µs | 19µs | CPAN::Meta::::BEGIN@151CPAN::Meta::BEGIN@151
1 | 1 | 1 | 10µs | 10µs | CPAN::Meta::::BEGIN@82CPAN::Meta::BEGIN@82
1 | 1 | 1 | 8µs | 8µs | main::::CORE:say main::CORE:say (opcode)
1 | 1 | 1 | 8µs | 8µs | CPAN::Meta::::BEGIN@114CPAN::Meta::BEGIN@114
1 | 1 | 1 | 7µs | 7µs | main::::BEGIN@1 main::BEGIN@1
1 | 1 | 1 | 7µs | 82µs | CPAN::Meta::::createCPAN::Meta::create
1 | 1 | 1 | 7µs | 73µs | CPAN::Meta::::_newCPAN::Meta::_new
1 | 1 | 1 | 5µs | 11µs | CPAN::Meta::::BEGIN@625CPAN::Meta::BEGIN@625
1 | 1 | 1 | 4µs | 4µs | CPAN::Meta::::BEGIN@58CPAN::Meta::BEGIN@58
1 | 1 | 1 | 4µs | 4µs | CPAN::Meta::::BEGIN@60CPAN::Meta::BEGIN@60
1 | 1 | 1 | 3µs | 7µs | CPAN::Meta::::BEGIN@121CPAN::Meta::BEGIN@121
1 | 1 | 1 | 3µs | 10µs | main::::BEGIN@3.2 main::BEGIN@3.2
1 | 1 | 1 | 3µs | 8µs | CPAN::Meta::::BEGIN@162CPAN::Meta::BEGIN@162
1 | 1 | 1 | 3µs | 7µs | CPAN::Meta::::BEGIN@61CPAN::Meta::BEGIN@61
1 | 1 | 1 | 3µs | 4µs | main::::BEGIN@2.1 main::BEGIN@2.1
1 | 1 | 1 | 3µs | 18µs | CPAN::Meta::::BEGIN@56CPAN::Meta::BEGIN@56
6 | 1 | 1 | 3µs | 3µs | CPAN::Meta::::CORE:substCPAN::Meta::CORE:subst (opcode)
1 | 1 | 1 | 2µs | 8µs | CPAN::Meta::::BEGIN@93CPAN::Meta::BEGIN@93
1 | 1 | 1 | 1µs | 1µs | CPAN::Meta::::BEGIN@63CPAN::Meta::BEGIN@63
4 | 4 | 1 | 1µs | 1µs | CPAN::Meta::::__ANON__CPAN::Meta::__ANON__ (xsub)
1 | 1 | 1 | 500ns | 500ns | main::::__ANON__ main::__ANON__ (xsub)
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::TO_JSONCPAN::Meta::TO_JSON
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::__ANON__[:129]CPAN::Meta::__ANON__[:129]
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::__ANON__[:169]CPAN::Meta::__ANON__[:169]
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::__ANON__[:95]CPAN::Meta::__ANON__[:95]
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::as_stringCPAN::Meta::as_string
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::as_structCPAN::Meta::as_struct
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::authorsCPAN::Meta::authors
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::customCPAN::Meta::custom
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::custom_keysCPAN::Meta::custom_keys
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::effective_prereqsCPAN::Meta::effective_prereqs
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::featureCPAN::Meta::feature
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::featuresCPAN::Meta::features
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::licensesCPAN::Meta::licenses
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::load_fileCPAN::Meta::load_file
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::load_json_stringCPAN::Meta::load_json_string
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::load_stringCPAN::Meta::load_string
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::load_yaml_stringCPAN::Meta::load_yaml_string
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::meta_spec_versionCPAN::Meta::meta_spec_version
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::newCPAN::Meta::new
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::saveCPAN::Meta::save
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::should_index_fileCPAN::Meta::should_index_file
0 | 0 | 0 | 0s | 0s | CPAN::Meta::::should_index_packageCPAN::Meta::should_index_package
0 | 0 | 0 | 0s | 0s | main::::RUNTIME main::RUNTIME

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 | 1 | 7µs | # spent 7µs within main::BEGIN@1 which was called: # once (7µs+0s) by main::BEGIN@4 at line 1 use 5.006; # spent 7µs making 1 call to main::BEGIN@1
2 | 2 | 9µs | 2 | 5µs | # spent 4µs (3+1) within main::BEGIN@2.1 which was called: # once (3µs+1µs) by main::BEGIN@4 at line 2 use strict; # spent 4µs making 1 call to main::BEGIN@2.1 # spent 1µs making 1 call to strict::import
3 | 2 | 39µs | 2 | 18µs | # spent 10µs (3+7) within main::BEGIN@3.2 which was called: # once (3µs+7µs) by main::BEGIN@4 at line 3 use warnings; # spent 10µs making 1 call to main::BEGIN@3.2 # spent 7µs making 1 call to warnings::import
4 |  |  |  |  | package CPAN::Meta;
5 |  |  |  |  |
6 | 1 | 200ns |  |  | our $VERSION = '2.150010';
7 |  |  |  |  |
8 |  |  |  |  | #pod =head1 SYNOPSIS
9 |  |  |  |  | #pod
10 |  |  |  |  | #pod use v5.10;
11 |  |  |  |  | #pod use strict;
12 |  |  |  |  | #pod use warnings;
13 |  |  |  |  | #pod use CPAN::Meta;
14 |  |  |  |  | #pod use Module::Load;
15 |  |  |  |  | #pod
16 |  |  |  |  | #pod my $meta = CPAN::Meta->load_file('META.json');
17 |  |  |  |  | #pod
18 |  |  |  |  | #pod printf "testing requirements for %s version %s\n",
19 |  |  |  |  | #pod $meta->name,
20 |  |  |  |  | #pod $meta->version;
21 |  |  |  |  | #pod
22 |  |  |  |  | #pod my $prereqs = $meta->effective_prereqs;
23 |  |  |  |  | #pod
24 |  |  |  |  | #pod for my $phase ( qw/configure runtime build test/ ) {
25 |  |  |  |  | #pod say "Requirements for $phase:";
26 |  |  |  |  | #pod my $reqs = $prereqs->requirements_for($phase, "requires");
27 |  |  |  |  | #pod for my $module ( sort $reqs->required_modules ) {
28 |  |  |  |  | #pod my $status;
29 |  |  |  |  | #pod if ( eval { load $module unless $module eq 'perl'; 1 } ) {
30 |  |  |  |  | #pod my $version = $module eq 'perl' ? $] : $module->VERSION;
31 |  |  |  |  | #pod $status = $reqs->accepts_module($module, $version)
32 |  |  |  |  | #pod ? "$version ok" : "$version not ok";
33 |  |  |  |  | #pod } else {
34 |  |  |  |  | #pod $status = "missing"
35 |  |  |  |  | #pod };
36 |  |  |  |  | #pod say " $module ($status)";
37 |  |  |  |  | #pod }
38 |  |  |  |  | #pod }
39 |  |  |  |  | #pod
40 |  |  |  |  | #pod =head1 DESCRIPTION
41 |  |  |  |  | #pod
42 |  |  |  |  | #pod Software distributions released to the CPAN include a F<META.json> or, for
43 |  |  |  |  | #pod older distributions, F<META.yml>, which describes the distribution, its
44 |  |  |  |  | #pod contents, and the requirements for building and installing the distribution.
45 |  |  |  |  | #pod The data structure stored in the F<META.json> file is described in
46 |  |  |  |  | #pod L<CPAN::Meta::Spec>.
47 |  |  |  |  | #pod
48 |  |  |  |  | #pod CPAN::Meta provides a simple class to represent this distribution metadata (or
49 |  |  |  |  | #pod I<distmeta>), along with some helpful methods for interrogating that data.
50 |  |  |  |  | #pod
51 |  |  |  |  | #pod The documentation below is only for the methods of the CPAN::Meta object. For
52 |  |  |  |  | #pod information on the meaning of individual fields, consult the spec.
53 |  |  |  |  | #pod
54 |  |  |  |  | #pod =cut
55 |  |  |  |  |
56 | 2 | 12µs | 2 | 32µs | # spent 18µs (3+15) within CPAN::Meta::BEGIN@56 which was called: # once (3µs+15µs) by main::BEGIN@4 at line 56 use Carp qw(carp croak); # spent 18µs making 1 call to CPAN::Meta::BEGIN@56 # spent 15µs making 1 call to Exporter::import
57 | 2 | 51µs | 2 | 3.79ms | # spent 3.79ms (181µs+3.60) within CPAN::Meta::BEGIN@57 which was called: # once (181µs+3.60ms) by main::BEGIN@4 at line 57 use CPAN::Meta::Feature; # spent 3.79ms making 1 call to CPAN::Meta::BEGIN@57 # spent 400ns making 1 call to CPAN::Meta::__ANON__
58 | 2 | 11µs | 2 | 4µs | # spent 4µs (4+200ns) within CPAN::Meta::BEGIN@58 which was called: # once (4µs+200ns) by main::BEGIN@4 at line 58 use CPAN::Meta::Prereqs; # spent 4µs making 1 call to CPAN::Meta::BEGIN@58 # spent 200ns making 1 call to CPAN::Meta::__ANON__
59 | 2 | 58µs | 2 | 7.00ms | # spent 7.00ms (3.88+3.12) within CPAN::Meta::BEGIN@59 which was called: # once (3.88ms+3.12ms) by main::BEGIN@4 at line 59 use CPAN::Meta::Converter; # spent 7.00ms making 1 call to CPAN::Meta::BEGIN@59 # spent 300ns making 1 call to CPAN::Meta::__ANON__
60 | 2 | 14µs | 2 | 4µs | # spent 4µs (4+200ns) within CPAN::Meta::BEGIN@60 which was called: # once (4µs+200ns) by main::BEGIN@4 at line 60 use CPAN::Meta::Validator; # spent 4µs making 1 call to CPAN::Meta::BEGIN@60 # spent 200ns making 1 call to CPAN::Meta::__ANON__
61 | 3 | 20µs | 2 | 11µs | # spent 7µs (3+4) within CPAN::Meta::BEGIN@61 which was called: # once (3µs+4µs) by main::BEGIN@4 at line 61 use Parse::CPAN::Meta 1.4414 (); # spent 7µs making 1 call to CPAN::Meta::BEGIN@61 # spent 4µs making 1 call to UNIVERSAL::VERSION
62 |  |  |  |  |
63 | 1 | 23µs | 1 | 1µs | # spent 1µs within CPAN::Meta::BEGIN@63 which was called: # once (1µs+0s) by main::BEGIN@4 at line 63 BEGIN { *_dclone = \&CPAN::Meta::Converter::_dclone } # spent 1µs making 1 call to CPAN::Meta::BEGIN@63
64 |  |  |  |  |
65 |  |  |  |  | #pod =head1 STRING DATA
66 |  |  |  |  | #pod
67 |  |  |  |  | #pod The following methods return a single value, which is the value for the
68 |  |  |  |  | #pod corresponding entry in the distmeta structure. Values should be either undef
69 |  |  |  |  | #pod or strings.
70 |  |  |  |  | #pod
71 |  |  |  |  | #pod =for :list
72 |  |  |  |  | #pod * abstract
73 |  |  |  |  | #pod * description
74 |  |  |  |  | #pod * dynamic_config
75 |  |  |  |  | #pod * generated_by
76 |  |  |  |  | #pod * name
77 |  |  |  |  | #pod * release_status
78 |  |  |  |  | #pod * version
79 |  |  |  |  | #pod
80 |  |  |  |  | #pod =cut
81 |  |  |  |  |
82 |  |  |  |  | # spent 10µs within CPAN::Meta::BEGIN@82 which was called: # once (10µs+0s) by main::BEGIN@4 at line 97 BEGIN {
83 | 1 | 700ns |  |  | my @STRING_READERS = qw(
84 |  |  |  |  | abstract
85 |  |  |  |  | description
86 |  |  |  |  | dynamic_config
87 |  |  |  |  | generated_by
88 |  |  |  |  | name
89 |  |  |  |  | release_status
90 |  |  |  |  | version
91 |  |  |  |  | );
92 |  |  |  |  |
93 | 2 | 26µs | 2 | 13µs | # spent 8µs (2+5) within CPAN::Meta::BEGIN@93 which was called: # once (2µs+5µs) by main::BEGIN@4 at line 93 no strict 'refs'; # spent 8µs making 1 call to CPAN::Meta::BEGIN@93 # spent 5µs making 1 call to strict::unimport
94 | 1 | 2µs |  |  | for my $attr (@STRING_READERS) {
95 | 7 | 8µs |  |  | *$attr = sub { $_[0]{ $attr } };
96 |  |  |  |  | }
97 | 1 | 20µs | 1 | 10µs | } # spent 10µs making 1 call to CPAN::Meta::BEGIN@82
98 |  |  |  |  |
99 |  |  |  |  | #pod =head1 LIST DATA
100 |  |  |  |  | #pod
101 |  |  |  |  | #pod These methods return lists of string values, which might be represented in the
102 |  |  |  |  | #pod distmeta structure as arrayrefs or scalars:
103 |  |  |  |  | #pod
104 |  |  |  |  | #pod =for :list
105 |  |  |  |  | #pod * authors
106 |  |  |  |  | #pod * keywords
107 |  |  |  |  | #pod * licenses
108 |  |  |  |  | #pod
109 |  |  |  |  | #pod The C<authors> and C<licenses> methods may also be called as C<author> and
110 |  |  |  |  | #pod C<license>, respectively, to match the field name in the distmeta structure.
111 |  |  |  |  | #pod
112 |  |  |  |  | #pod =cut
113 |  |  |  |  |
114 |  |  |  |  | # spent 8µs within CPAN::Meta::BEGIN@114 which was called: # once (8µs+0s) by main::BEGIN@4 at line 131 BEGIN {
115 | 1 | 500ns |  |  | my @LIST_READERS = qw(
116 |  |  |  |  | author
117 |  |  |  |  | keywords
118 |  |  |  |  | license
119 |  |  |  |  | );
120 |  |  |  |  |
121 | 2 | 42µs | 2 | 11µs | # spent 7µs (3+4) within CPAN::Meta::BEGIN@121 which was called: # once (3µs+4µs) by main::BEGIN@4 at line 121 no strict 'refs'; # spent 7µs making 1 call to CPAN::Meta::BEGIN@121 # spent 4µs making 1 call to strict::unimport
122 | 1 | 4µs |  |  | for my $attr (@LIST_READERS) {
123 |  |  |  |  | *$attr = sub {
124 |  |  |  |  | my $value = $_[0]{ $attr };
125 |  |  |  |  | croak "$attr must be called in list context"
126 |  |  |  |  | unless wantarray;
127 |  |  |  |  | return @{ _dclone($value) } if ref $value;
128 |  |  |  |  | return $value;
129 | 3 | 6µs |  |  | };
130 |  |  |  |  | }
131 | 1 | 37µs | 1 | 8µs | } # spent 8µs making 1 call to CPAN::Meta::BEGIN@114
132 |  |  |  |  |
133 |  |  |  |  | sub authors { $_[0]->author }
134 |  |  |  |  | sub licenses { $_[0]->license }
135 |  |  |  |  |
136 |  |  |  |  | #pod =head1 MAP DATA
137 |  |  |  |  | #pod
138 |  |  |  |  | #pod These readers return hashrefs of arbitrary unblessed data structures, each
139 |  |  |  |  | #pod described more fully in the specification:
140 |  |  |  |  | #pod
141 |  |  |  |  | #pod =for :list
142 |  |  |  |  | #pod * meta_spec
143 |  |  |  |  | #pod * resources
144 |  |  |  |  | #pod * provides
145 |  |  |  |  | #pod * no_index
146 |  |  |  |  | #pod * prereqs
147 |  |  |  |  | #pod * optional_features
148 |  |  |  |  | #pod
149 |  |  |  |  | #pod =cut
150 |  |  |  |  |
151 |  |  |  |  | # spent 19µs (16+3) within CPAN::Meta::BEGIN@151 which was called: # once (16µs+3µs) by main::BEGIN@4 at line 171 BEGIN {
152 | 1 | 600ns |  |  | my @MAP_READERS = qw(
153 |  |  |  |  | meta-spec
154 |  |  |  |  | resources
155 |  |  |  |  | provides
156 |  |  |  |  | no_index
157 |  |  |  |  |
158 |  |  |  |  | prereqs
159 |  |  |  |  | optional_features
160 |  |  |  |  | );
161 |  |  |  |  |
162 | 2 | 44µs | 2 | 12µs | # spent 8µs (3+4) within CPAN::Meta::BEGIN@162 which was called: # once (3µs+4µs) by main::BEGIN@4 at line 162 no strict 'refs'; # spent 8µs making 1 call to CPAN::Meta::BEGIN@162 # spent 4µs making 1 call to strict::unimport
163 | 1 | 1µs |  |  | for my $attr (@MAP_READERS) {
164 | 6 | 8µs | 6 | 3µs | (my $subname = $attr) =~ s/-/_/; # spent 3µs making 6 calls to CPAN::Meta::CORE:subst, avg 450ns/call
165 |  |  |  |  | *$subname = sub {
166 |  |  |  |  | my $value = $_[0]{ $attr };
167 |  |  |  |  | return _dclone($value) if $value;
168 |  |  |  |  | return {};
169 | 6 | 9µs |  |  | };
170 |  |  |  |  | }
171 | 1 | 728µs | 1 | 19µs | } # spent 19µs making 1 call to CPAN::Meta::BEGIN@151
172 |  |  |  |  |
173 |  |  |  |  | #pod =head1 CUSTOM DATA
174 |  |  |  |  | #pod
175 |  |  |  |  | #pod A list of custom keys are available from the C<custom_keys> method and
176 |  |  |  |  | #pod particular keys may be retrieved with the C<custom> method.
177 |  |  |  |  | #pod
178 |  |  |  |  | #pod say $meta->custom($_) for $meta->custom_keys;
179 |  |  |  |  | #pod
180 |  |  |  |  | #pod If a custom key refers to a data structure, a deep clone is returned.
181 |  |  |  |  | #pod
182 |  |  |  |  | #pod =cut
183 |  |  |  |  |
184 |  |  |  |  | sub custom_keys {
185 |  |  |  |  | return grep { /^x_/i } keys %{$_[0]};
186 |  |  |  |  | }
187 |  |  |  |  |
188 |  |  |  |  | sub custom {
189 |  |  |  |  | my ($self, $attr) = @_;
190 |  |  |  |  | my $value = $self->{$attr};
191 |  |  |  |  | return _dclone($value) if ref $value;
192 |  |  |  |  | return $value;
193 |  |  |  |  | }
194 |  |  |  |  |
195 |  |  |  |  | #pod =method new
196 |  |  |  |  | #pod
197 |  |  |  |  | #pod my $meta = CPAN::Meta->new($distmeta_struct, \%options);
198 |  |  |  |  | #pod
199 |  |  |  |  | #pod Returns a valid CPAN::Meta object or dies if the supplied metadata hash
200 |  |  |  |  | #pod reference fails to validate. Older-format metadata will be up-converted to
201 |  |  |  |  | #pod version 2 if they validate against the original stated specification.
202 |  |  |  |  | #pod
203 |  |  |  |  | #pod It takes an optional hashref of options. Valid options include:
204 |  |  |  |  | #pod
205 |  |  |  |  | #pod =over
206 |  |  |  |  | #pod
207 |  |  |  |  | #pod =item *
208 |  |  |  |  | #pod
209 |  |  |  |  | #pod lazy_validation -- if true, new will attempt to convert the given metadata
210 |  |  |  |  | #pod to version 2 before attempting to validate it. This means than any
211 |  |  |  |  | #pod fixable errors will be handled by CPAN::Meta::Converter before validation.
212 |  |  |  |  | #pod (Note that this might result in invalid optional data being silently
213 |  |  |  |  | #pod dropped.) The default is false.
214 |  |  |  |  | #pod
215 |  |  |  |  | #pod =back
216 |  |  |  |  | #pod
217 |  |  |  |  | #pod =cut
218 |  |  |  |  |
219 |  |  |  |  | # spent 73µs (7+66) within CPAN::Meta::_new which was called: # once (7µs+66µs) by CPAN::Meta::create at line 273 sub _new {
220 | 1 | 300ns |  |  | my ($class, $struct, $options) = @_;
221 | 1 | 0s |  |  | my $self;
222 |  |  |  |  |
223 | 1 | 400ns |  |  | if ( $options->{lazy_validation} ) {
224 |  |  |  |  | # try to convert to a valid structure; if succeeds, then return it
225 |  |  |  |  | my $cmc = CPAN::Meta::Converter->new( $struct );
226 |  |  |  |  | $self = $cmc->convert( version => 2 ); # valid or dies
227 |  |  |  |  | return bless $self, $class;
228 |  |  |  |  | }
229 |  |  |  |  | else {
230 |  |  |  |  | # validate original struct
231 | 1 | 600ns | 1 | 2µs | my $cmv = CPAN::Meta::Validator->new( $struct ); # spent 2µs making 1 call to CPAN::Meta::Validator::new
232 | 1 | 2µs | 1 | 64µs | unless ( $cmv->is_valid) { # spent 64µs making 1 call to CPAN::Meta::Validator::is_valid
233 |  |  |  |  | die "Invalid metadata structure. Errors: "
234 |  |  |  |  | . join(", ", $cmv->errors) . "\n";
235 |  |  |  |  | }
236 |  |  |  |  | }
237 |  |  |  |  |
238 |  |  |  |  | # up-convert older spec versions
239 | 1 | 200ns |  |  | my $version = $struct->{'meta-spec'}{version} || '1.0';
240 | 1 | 200ns |  |  | if ( $version == 2 ) {
241 |  |  |  |  | $self = $struct;
242 |  |  |  |  | }
243 |  |  |  |  | else {
244 |  |  |  |  | my $cmc = CPAN::Meta::Converter->new( $struct );
245 |  |  |  |  | $self = $cmc->convert( version => 2 );
246 |  |  |  |  | }
247 |  |  |  |  |
248 | 1 | 2µs |  |  | return bless $self, $class;
249 |  |  |  |  | }
250 |  |  |  |  |
251 |  |  |  |  | sub new {
252 |  |  |  |  | my ($class, $struct, $options) = @_;
253 |  |  |  |  | my $self = eval { $class->_new($struct, $options) };
254 |  |  |  |  | croak($@) if $@;
255 |  |  |  |  | return $self;
256 |  |  |  |  | }
257 |  |  |  |  |
258 |  |  |  |  | #pod =method create
259 |  |  |  |  | #pod
260 |  |  |  |  | #pod my $meta = CPAN::Meta->create($distmeta_struct, \%options);
261 |  |  |  |  | #pod
262 |  |  |  |  | #pod This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
263 |  |  |  |  | #pod will be generated if not provided. This means the metadata structure is
264 |  |  |  |  | #pod assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
265 |  |  |  |  | #pod
266 |  |  |  |  | #pod =cut
267 |  |  |  |  |
268 |  |  |  |  | # spent 82µs (7+75) within CPAN::Meta::create which was called: # once (7µs+75µs) by main::RUNTIME at line 5 of /home/leont/Code/cpan/experimental/test.pl sub create {
269 | 1 | 400ns |  |  | my ($class, $struct, $options) = @_;
270 | 1 | 5µs | 1 | 2µs | my $version = __PACKAGE__->VERSION || 2; # spent 2µs making 1 call to UNIVERSAL::VERSION
271 | 1 | 800ns |  |  | $struct->{generated_by} ||= __PACKAGE__ . " version $version" ;
272 | 1 | 200ns |  |  | $struct->{'meta-spec'}{version} ||= int($version);
273 | 2 | 1µs | 1 | 73µs | my $self = eval { $class->_new($struct, $options) }; # spent 73µs making 1 call to CPAN::Meta::_new
274 | 1 | 100ns |  |  | croak ($@) if $@;
275 | 1 | 2µs |  |  | return $self;
276 |  |  |  |  | }
277 |  |  |  |  |
278 |  |  |  |  | #pod =method load_file
279 |  |  |  |  | #pod
280 |  |  |  |  | #pod my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
281 |  |  |  |  | #pod
282 |  |  |  |  | #pod Given a pathname to a file containing metadata, this deserializes the file
283 |  |  |  |  | #pod according to its file suffix and constructs a new C<CPAN::Meta> object, just
284 |  |  |  |  | #pod like C<new()>. It will die if the deserialized version fails to validate
285 |  |  |  |  | #pod against its stated specification version.
286 |  |  |  |  | #pod
287 |  |  |  |  | #pod It takes the same options as C<new()> but C<lazy_validation> defaults to
288 |  |  |  |  | #pod true.
289 |  |  |  |  | #pod
290 |  |  |  |  | #pod =cut
291 |  |  |  |  |
292 |  |  |  |  | sub load_file {
293 |  |  |  |  | my ($class, $file, $options) = @_;
294 |  |  |  |  | $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
295 |  |  |  |  |
296 |  |  |  |  | croak "load_file() requires a valid, readable filename"
297 |  |  |  |  | unless -r $file;
298 |  |  |  |  |
299 |  |  |  |  | my $self;
300 |  |  |  |  | eval {
301 |  |  |  |  | my $struct = Parse::CPAN::Meta->load_file( $file );
302 |  |  |  |  | $self = $class->_new($struct, $options);
303 |  |  |  |  | };
304 |  |  |  |  | croak($@) if $@;
305 |  |  |  |  | return $self;
306 |  |  |  |  | }
307 |  |  |  |  |
308 |  |  |  |  | #pod =method load_yaml_string
309 |  |  |  |  | #pod
310 |  |  |  |  | #pod my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
311 |  |  |  |  | #pod
312 |  |  |  |  | #pod This method returns a new CPAN::Meta object using the first document in the
313 |  |  |  |  | #pod given YAML string. In other respects it is identical to C<load_file()>.
314 |  |  |  |  | #pod
315 |  |  |  |  | #pod =cut
316 |  |  |  |  |
317 |  |  |  |  | sub load_yaml_string {
318 |  |  |  |  | my ($class, $yaml, $options) = @_;
319 |  |  |  |  | $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
320 |  |  |  |  |
321 |  |  |  |  | my $self;
322 |  |  |  |  | eval {
323 |  |  |  |  | my ($struct) = Parse::CPAN::Meta->load_yaml_string( $yaml );
324 |  |  |  |  | $self = $class->_new($struct, $options);
325 |  |  |  |  | };
326 |  |  |  |  | croak($@) if $@;
327 |  |  |  |  | return $self;
328 |  |  |  |  | }
329 |  |  |  |  |
330 |  |  |  |  | #pod =method load_json_string
331 |  |  |  |  | #pod
332 |  |  |  |  | #pod my $meta = CPAN::Meta->load_json_string($json, \%options);
333 |  |  |  |  | #pod
334 |  |  |  |  | #pod This method returns a new CPAN::Meta object using the structure represented by
335 |  |  |  |  | #pod the given JSON string. In other respects it is identical to C<load_file()>.
336 |  |  |  |  | #pod
337 |  |  |  |  | #pod =cut
338 |  |  |  |  |
339 |  |  |  |  | sub load_json_string {
340 |  |  |  |  | my ($class, $json, $options) = @_;
341 |  |  |  |  | $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
342 |  |  |  |  |
343 |  |  |  |  | my $self;
344 |  |  |  |  | eval {
345 |  |  |  |  | my $struct = Parse::CPAN::Meta->load_json_string( $json );
346 |  |  |  |  | $self = $class->_new($struct, $options);
347 |  |  |  |  | };
348 |  |  |  |  | croak($@) if $@;
349 |  |  |  |  | return $self;
350 |  |  |  |  | }
351 |  |  |  |  |
352 |  |  |  |  | #pod =method load_string
353 |  |  |  |  | #pod
354 |  |  |  |  | #pod my $meta = CPAN::Meta->load_string($string, \%options);
355 |  |  |  |  | #pod
356 |  |  |  |  | #pod If you don't know if a string contains YAML or JSON, this method will use
357 |  |  |  |  | #pod L<Parse::CPAN::Meta> to guess. In other respects it is identical to
358 |  |  |  |  | #pod C<load_file()>.
359 |  |  |  |  | #pod
360 |  |  |  |  | #pod =cut
361 |  |  |  |  |
362 |  |  |  |  | sub load_string {
363 |  |  |  |  | my ($class, $string, $options) = @_;
364 |  |  |  |  | $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
365 |  |  |  |  |
366 |  |  |  |  | my $self;
367 |  |  |  |  | eval {
368 |  |  |  |  | my $struct = Parse::CPAN::Meta->load_string( $string );
369 |  |  |  |  | $self = $class->_new($struct, $options);
370 |  |  |  |  | };
371 |  |  |  |  | croak($@) if $@;
372 |  |  |  |  | return $self;
373 |  |  |  |  | }
374 |  |  |  |  |
375 |  |  |  |  | #pod =method save
376 |  |  |  |  | #pod
377 |  |  |  |  | #pod $meta->save($distmeta_file, \%options);
378 |  |  |  |  | #pod
379 |  |  |  |  | #pod Serializes the object as JSON and writes it to the given file. The only valid
380 |  |  |  |  | #pod option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
381 |  |  |  |  | #pod is saved with UTF-8 encoding.
382 |  |  |  |  | #pod
383 |  |  |  |  | #pod For C<version> 2 (or higher), the filename should end in '.json'. L<JSON::PP>
384 |  |  |  |  | #pod is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
385 |  |  |  |  | #pod later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
386 |  |  |  |  | #pod backend like L<JSON::XS>.
387 |  |  |  |  | #pod
388 |  |  |  |  | #pod For C<version> less than 2, the filename should end in '.yml'.
389 |  |  |  |  | #pod L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
390 |  |  |  |  | #pod is serialized to YAML. CPAN::Meta::YAML is the default YAML backend. You may
391 |  |  |  |  | #pod set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
392 |  |  |  |  | #pod this is not recommended due to subtle incompatibilities between YAML parsers on
393 |  |  |  |  | #pod CPAN.
394 |  |  |  |  | #pod
395 |  |  |  |  | #pod =cut
396 |  |  |  |  |
397 |  |  |  |  | sub save {
398 |  |  |  |  | my ($self, $file, $options) = @_;
399 |  |  |  |  |
400 |  |  |  |  | my $version = $options->{version} || '2';
401 |  |  |  |  | my $layer = $] ge '5.008001' ? ':utf8' : '';
402 |  |  |  |  |
403 |  |  |  |  | if ( $version ge '2' ) {
404 |  |  |  |  | carp "'$file' should end in '.json'"
405 |  |  |  |  | unless $file =~ m{\.json$};
406 |  |  |  |  | }
407 |  |  |  |  | else {
408 |  |  |  |  | carp "'$file' should end in '.yml'"
409 |  |  |  |  | unless $file =~ m{\.yml$};
410 |  |  |  |  | }
411 |  |  |  |  |
412 |  |  |  |  | my $data = $self->as_string( $options );
413 |  |  |  |  | open my $fh, ">$layer", $file
414 |  |  |  |  | or die "Error opening '$file' for writing: $!\n";
415 |  |  |  |  |
416 |  |  |  |  | print {$fh} $data;
417 |  |  |  |  | close $fh
418 |  |  |  |  | or die "Error closing '$file': $!\n";
419 |  |  |  |  |
420 |  |  |  |  | return 1;
421 |  |  |  |  | }
422 |  |  |  |  |
423 |  |  |  |  | #pod =method meta_spec_version
424 |  |  |  |  | #pod
425 |  |  |  |  | #pod This method returns the version part of the C<meta_spec> entry in the distmeta
426 |  |  |  |  | #pod structure. It is equivalent to:
427 |  |  |  |  | #pod
428 |  |  |  |  | #pod $meta->meta_spec->{version};
429 |  |  |  |  | #pod
430 |  |  |  |  | #pod =cut
431 |  |  |  |  |
432 |  |  |  |  | sub meta_spec_version {
433 |  |  |  |  | my ($self) = @_;
434 |  |  |  |  | return $self->meta_spec->{version};
435 |  |  |  |  | }
436 |  |  |  |  |
437 |  |  |  |  | #pod =method effective_prereqs
438 |  |  |  |  | #pod
439 |  |  |  |  | #pod my $prereqs = $meta->effective_prereqs;
440 |  |  |  |  | #pod
441 |  |  |  |  | #pod my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
442 |  |  |  |  | #pod
443 |  |  |  |  | #pod This method returns a L<CPAN::Meta::Prereqs> object describing all the
444 |  |  |  |  | #pod prereqs for the distribution. If an arrayref of feature identifiers is given,
445 |  |  |  |  | #pod the prereqs for the identified features are merged together with the
446 |  |  |  |  | #pod distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
447 |  |  |  |  | #pod
448 |  |  |  |  | #pod =cut
449 |  |  |  |  |
450 |  |  |  |  | sub effective_prereqs {
451 |  |  |  |  | my ($self, $features) = @_;
452 |  |  |  |  | $features ||= [];
453 |  |  |  |  |
454 |  |  |  |  | my $prereq = CPAN::Meta::Prereqs->new($self->prereqs);
455 |  |  |  |  |
456 |  |  |  |  | return $prereq unless @$features;
457 |  |  |  |  |
458 |  |  |  |  | my @other = map {; $self->feature($_)->prereqs } @$features;
459 |  |  |  |  |
460 |  |  |  |  | return $prereq->with_merged_prereqs(\@other);
461 |  |  |  |  | }
462 |  |  |  |  |
463 |  |  |  |  | #pod =method should_index_file
464 |  |  |  |  | #pod
465 |  |  |  |  | #pod ... if $meta->should_index_file( $filename );
466 |  |  |  |  | #pod
467 |  |  |  |  | #pod This method returns true if the given file should be indexed. It decides this
468 |  |  |  |  | #pod by checking the C<file> and C<directory> keys in the C<no_index> property of
469 |  |  |  |  | #pod the distmeta structure. Note that neither the version format nor
470 |  |  |  |  | #pod C<release_status> are considered.
471 |  |  |  |  | #pod
472 |  |  |  |  | #pod C<$filename> should be given in unix format.
473 |  |  |  |  | #pod
474 |  |  |  |  | #pod =cut
475 |  |  |  |  |
476 |  |  |  |  | sub should_index_file {
477 |  |  |  |  | my ($self, $filename) = @_;
478 |  |  |  |  |
479 |  |  |  |  | for my $no_index_file (@{ $self->no_index->{file} || [] }) {
480 |  |  |  |  | return if $filename eq $no_index_file;
481 |  |  |  |  | }
482 |  |  |  |  |
483 |  |  |  |  | for my $no_index_dir (@{ $self->no_index->{directory} }) {
484 |  |  |  |  | $no_index_dir =~ s{$}{/} unless $no_index_dir =~ m{/\z};
485 |  |  |  |  | return if index($filename, $no_index_dir) == 0;
486 |  |  |  |  | }
487 |  |  |  |  |
488 |  |  |  |  | return 1;
489 |  |  |  |  | }
490 |  |  |  |  |
491 |  |  |  |  | #pod =method should_index_package
492 |  |  |  |  | #pod
493 |  |  |  |  | #pod ... if $meta->should_index_package( $package );
494 |  |  |  |  | #pod
495 |  |  |  |  | #pod This method returns true if the given package should be indexed. It decides
496 |  |  |  |  | #pod this by checking the C<package> and C<namespace> keys in the C<no_index>
497 |  |  |  |  | #pod property of the distmeta structure. Note that neither the version format nor
498 |  |  |  |  | #pod C<release_status> are considered.
499 |  |  |  |  | #pod
500 |  |  |  |  | #pod =cut
501 |  |  |  |  |
502 |  |  |  |  | sub should_index_package {
503 |  |  |  |  | my ($self, $package) = @_;
504 |  |  |  |  |
505 |  |  |  |  | for my $no_index_pkg (@{ $self->no_index->{package} || [] }) {
506 |  |  |  |  | return if $package eq $no_index_pkg;
507 |  |  |  |  | }
508 |  |  |  |  |
509 |  |  |  |  | for my $no_index_ns (@{ $self->no_index->{namespace} }) {
510 |  |  |  |  | return if index($package, "${no_index_ns}::") == 0;
511 |  |  |  |  | }
512 |  |  |  |  |
513 |  |  |  |  | return 1;
514 |  |  |  |  | }
515 |  |  |  |  |
516 |  |  |  |  | #pod =method features
517 |  |  |  |  | #pod
518 |  |  |  |  | #pod my @feature_objects = $meta->features;
519 |  |  |  |  | #pod
520 |  |  |  |  | #pod This method returns a list of L<CPAN::Meta::Feature> objects, one for each
521 |  |  |  |  | #pod optional feature described by the distribution's metadata.
522 |  |  |  |  | #pod
523 |  |  |  |  | #pod =cut
524 |  |  |  |  |
525 |  |  |  |  | sub features {
526 |  |  |  |  | my ($self) = @_;
527 |  |  |  |  |
528 |  |  |  |  | my $opt_f = $self->optional_features;
529 |  |  |  |  | my @features = map {; CPAN::Meta::Feature->new($_ => $opt_f->{ $_ }) }
530 |  |  |  |  | keys %$opt_f;
531 |  |  |  |  |
532 |  |  |  |  | return @features;
533 |  |  |  |  | }
534 |  |  |  |  |
535 |  |  |  |  | #pod =method feature
536 |  |  |  |  | #pod
537 |  |  |  |  | #pod my $feature_object = $meta->feature( $identifier );
538 |  |  |  |  | #pod
539 |  |  |  |  | #pod This method returns a L<CPAN::Meta::Feature> object for the optional feature
540 |  |  |  |  | #pod with the given identifier. If no feature with that identifier exists, an
541 |  |  |  |  | #pod exception will be raised.
542 |  |  |  |  | #pod
543 |  |  |  |  | #pod =cut
544 |  |  |  |  |
545 |  |  |  |  | sub feature {
546 |  |  |  |  | my ($self, $ident) = @_;
547 |  |  |  |  |
548 |  |  |  |  | croak "no feature named $ident"
549 |  |  |  |  | unless my $f = $self->optional_features->{ $ident };
550 |  |  |  |  |
551 |  |  |  |  | return CPAN::Meta::Feature->new($ident, $f);
552 |  |  |  |  | }
553 |  |  |  |  |
554 |  |  |  |  | #pod =method as_struct
555 |  |  |  |  | #pod
556 |  |  |  |  | #pod my $copy = $meta->as_struct( \%options );
557 |  |  |  |  | #pod
558 |  |  |  |  | #pod This method returns a deep copy of the object's metadata as an unblessed hash
559 |  |  |  |  | #pod reference. It takes an optional hashref of options. If the hashref contains
560 |  |  |  |  | #pod a C<version> argument, the copied metadata will be converted to the version
561 |  |  |  |  | #pod of the specification and returned. For example:
562 |  |  |  |  | #pod
563 |  |  |  |  | #pod my $old_spec = $meta->as_struct( {version => "1.4"} );
564 |  |  |  |  | #pod
565 |  |  |  |  | #pod =cut
566 |  |  |  |  |
567 |  |  |  |  | sub as_struct {
568 |  |  |  |  | my ($self, $options) = @_;
569 |  |  |  |  | my $struct = _dclone($self);
570 |  |  |  |  | if ( $options->{version} ) {
571 |  |  |  |  | my $cmc = CPAN::Meta::Converter->new( $struct );
572 |  |  |  |  | $struct = $cmc->convert( version => $options->{version} );
573 |  |  |  |  | }
574 |  |  |  |  | return $struct;
575 |  |  |  |  | }
576 |  |  |  |  |
577 |  |  |  |  | #pod =method as_string
578 |  |  |  |  | #pod
579 |  |  |  |  | #pod my $string = $meta->as_string( \%options );
580 |  |  |  |  | #pod
581 |  |  |  |  | #pod This method returns a serialized copy of the object's metadata as a character
582 |  |  |  |  | #pod string. (The strings are B<not> UTF-8 encoded.) It takes an optional hashref
583 |  |  |  |  | #pod of options. If the hashref contains a C<version> argument, the copied metadata
584 |  |  |  |  | #pod will be converted to the version of the specification and returned. For
585 |  |  |  |  | #pod example:
586 |  |  |  |  | #pod
587 |  |  |  |  | #pod my $string = $meta->as_string( {version => "1.4"} );
588 |  |  |  |  | #pod
589 |  |  |  |  | #pod For C<version> greater than or equal to 2, the string will be serialized as
590 |  |  |  |  | #pod JSON. For C<version> less than 2, the string will be serialized as YAML. In
591 |  |  |  |  | #pod both cases, the same rules are followed as in the C<save()> method for choosing
592 |  |  |  |  | #pod a serialization backend.
593 |  |  |  |  | #pod
594 |  |  |  |  | #pod The serialized structure will include a C<x_serialization_backend> entry giving
595 |  |  |  |  | #pod the package and version used to serialize. Any existing key in the given
596 |  |  |  |  | #pod C<$meta> object will be clobbered.
597 |  |  |  |  | #pod
598 |  |  |  |  | #pod =cut
599 |  |  |  |  |
600 |  |  |  |  | sub as_string {
601 |  |  |  |  | my ($self, $options) = @_;
602 |  |  |  |  |
603 |  |  |  |  | my $version = $options->{version} || '2';
604 |  |  |  |  |
605 |  |  |  |  | my $struct;
606 |  |  |  |  | if ( $self->meta_spec_version ne $version ) {
607 |  |  |  |  | my $cmc = CPAN::Meta::Converter->new( $self->as_struct );
608 |  |  |  |  | $struct = $cmc->convert( version => $version );
609 |  |  |  |  | }
610 |  |  |  |  | else {
611 |  |  |  |  | $struct = $self->as_struct;
612 |  |  |  |  | }
613 |  |  |  |  |
614 |  |  |  |  | my ($data, $backend);
615 |  |  |  |  | if ( $version ge '2' ) {
616 |  |  |  |  | $backend = Parse::CPAN::Meta->json_backend();
617 |  |  |  |  | local $struct->{x_serialization_backend} = sprintf '%s version %s',
618 |  |  |  |  | $backend, $backend->VERSION;
619 |  |  |  |  | $data = $backend->new->pretty->canonical->encode($struct);
620 |  |  |  |  | }
621 |  |  |  |  | else {
622 |  |  |  |  | $backend = Parse::CPAN::Meta->yaml_backend();
623 |  |  |  |  | local $struct->{x_serialization_backend} = sprintf '%s version %s',
624 |  |  |  |  | $backend, $backend->VERSION;
625 | 2 | 199µs | 2 | 17µs | # spent 11µs (5+6) within CPAN::Meta::BEGIN@625 which was called: # once (5µs+6µs) by main::BEGIN@4 at line 625 $data = eval { no strict 'refs'; &{"$backend\::Dump"}($struct) }; # spent 11µs making 1 call to CPAN::Meta::BEGIN@625 # spent 6µs making 1 call to strict::unimport
626 |  |  |  |  | if ( $@ ) {
627 |  |  |  |  | croak $backend->can('errstr') ? $backend->errstr : $@
628 |  |  |  |  | }
629 |  |  |  |  | }
630 |  |  |  |  |
631 |  |  |  |  | return $data;
632 |  |  |  |  | }
633 |  |  |  |  |
634 |  |  |  |  | # Used by JSON::PP, etc. for "convert_blessed"
635 |  |  |  |  | sub TO_JSON {
636 |  |  |  |  | return { %{ $_[0] } };
637 |  |  |  |  | }
638 |  |  |  |  |
639 | 1 | 2µs |  |  | 1;
640 |  |  |  |  |
641 |  |  |  |  | # ABSTRACT: the distribution metadata for a CPAN dist
642 |  |  |  |  |
643 |  |  |  |  | =pod
644 |  |  |  |  |
645 |  |  |  |  | =encoding UTF-8
646 |  |  |  |  |
647 |  |  |  |  | =head1 NAME
648 |  |  |  |  |
649 |  |  |  |  | CPAN::Meta - the distribution metadata for a CPAN dist
650 |  |  |  |  |
651 |  |  |  |  | =head1 VERSION
652 |  |  |  |  |
653 |  |  |  |  | version 2.150010
654 |  |  |  |  |
655 |  |  |  |  | =head1 SYNOPSIS
656 |  |  |  |  |
657 |  |  |  |  | use v5.10;
658 |  |  |  |  | use strict;
659 |  |  |  |  | use warnings;
660 |  |  |  |  | use CPAN::Meta;
661 |  |  |  |  | use Module::Load;
662 |  |  |  |  |
663 |  |  |  |  | my $meta = CPAN::Meta->load_file('META.json');
664 |  |  |  |  |
665 |  |  |  |  | printf "testing requirements for %s version %s\n",
666 |  |  |  |  | $meta->name,
667 |  |  |  |  | $meta->version;
668 |  |  |  |  |
669 |  |  |  |  | my $prereqs = $meta->effective_prereqs;
670 |  |  |  |  |
671 |  |  |  |  | for my $phase ( qw/configure runtime build test/ ) {
672 |  |  |  |  | say "Requirements for $phase:";
673 |  |  |  |  | my $reqs = $prereqs->requirements_for($phase, "requires");
674 |  |  |  |  | for my $module ( sort $reqs->required_modules ) {
675 |  |  |  |  | my $status;
676 |  |  |  |  | if ( eval { load $module unless $module eq 'perl'; 1 } ) {
677 |  |  |  |  | my $version = $module eq 'perl' ? $] : $module->VERSION;
678 |  |  |  |  | $status = $reqs->accepts_module($module, $version)
679 |  |  |  |  | ? "$version ok" : "$version not ok";
680 |  |  |  |  | } else {
681 |  |  |  |  | $status = "missing"
682 |  |  |  |  | };
683 |  |  |  |  | say " $module ($status)";
684 |  |  |  |  | }
685 |  |  |  |  | }
686 |  |  |  |  |
687 |  |  |  |  | =head1 DESCRIPTION
688 |  |  |  |  |
689 |  |  |  |  | Software distributions released to the CPAN include a F<META.json> or, for
690 |  |  |  |  | older distributions, F<META.yml>, which describes the distribution, its
691 |  |  |  |  | contents, and the requirements for building and installing the distribution.
692 |  |  |  |  | The data structure stored in the F<META.json> file is described in
693 |  |  |  |  | L<CPAN::Meta::Spec>.
694 |  |  |  |  |
695 |  |  |  |  | CPAN::Meta provides a simple class to represent this distribution metadata (or
696 |  |  |  |  | I<distmeta>), along with some helpful methods for interrogating that data.
697 |  |  |  |  |
698 |  |  |  |  | The documentation below is only for the methods of the CPAN::Meta object. For
699 |  |  |  |  | information on the meaning of individual fields, consult the spec.
700 |  |  |  |  |
701 |  |  |  |  | =head1 METHODS
702 |  |  |  |  |
703 |  |  |  |  | =head2 new
704 |  |  |  |  |
705 |  |  |  |  | my $meta = CPAN::Meta->new($distmeta_struct, \%options);
706 |  |  |  |  |
707 |  |  |  |  | Returns a valid CPAN::Meta object or dies if the supplied metadata hash
708 |  |  |  |  | reference fails to validate. Older-format metadata will be up-converted to
709 |  |  |  |  | version 2 if they validate against the original stated specification.
710 |  |  |  |  |
711 |  |  |  |  | It takes an optional hashref of options. Valid options include:
712 |  |  |  |  |
713 |  |  |  |  | =over
714 |  |  |  |  |
715 |  |  |  |  | =item *
716 |  |  |  |  |
717 |  |  |  |  | lazy_validation -- if true, new will attempt to convert the given metadata
718 |  |  |  |  | to version 2 before attempting to validate it. This means than any
719 |  |  |  |  | fixable errors will be handled by CPAN::Meta::Converter before validation.
720 |  |  |  |  | (Note that this might result in invalid optional data being silently
721 |  |  |  |  | dropped.) The default is false.
722 |  |  |  |  |
723 |  |  |  |  | =back
724 |  |  |  |  |
725 |  |  |  |  | =head2 create
726 |  |  |  |  |
727 |  |  |  |  | my $meta = CPAN::Meta->create($distmeta_struct, \%options);
728 |  |  |  |  |
729 |  |  |  |  | This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
730 |  |  |  |  | will be generated if not provided. This means the metadata structure is
731 |  |  |  |  | assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
732 |  |  |  |  |
733 |  |  |  |  | =head2 load_file
734 |  |  |  |  |
735 |  |  |  |  | my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
736 |  |  |  |  |
737 |  |  |  |  | Given a pathname to a file containing metadata, this deserializes the file
738 |  |  |  |  | according to its file suffix and constructs a new C<CPAN::Meta> object, just
739 |  |  |  |  | like C<new()>. It will die if the deserialized version fails to validate
740 |  |  |  |  | against its stated specification version.
741 |  |  |  |  |
742 |  |  |  |  | It takes the same options as C<new()> but C<lazy_validation> defaults to
743 |  |  |  |  | true.
744 |  |  |  |  |
745 |  |  |  |  | =head2 load_yaml_string
746 |  |  |  |  |
747 |  |  |  |  | my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
748 |  |  |  |  |
749 |  |  |  |  | This method returns a new CPAN::Meta object using the first document in the
750 |  |  |  |  | given YAML string. In other respects it is identical to C<load_file()>.
751 |  |  |  |  |
752 |  |  |  |  | =head2 load_json_string
753 |  |  |  |  |
754 |  |  |  |  | my $meta = CPAN::Meta->load_json_string($json, \%options);
755 |  |  |  |  |
756 |  |  |  |  | This method returns a new CPAN::Meta object using the structure represented by
757 |  |  |  |  | the given JSON string. In other respects it is identical to C<load_file()>.
758 |  |  |  |  |
759 |  |  |  |  | =head2 load_string
760 |  |  |  |  |
761 |  |  |  |  | my $meta = CPAN::Meta->load_string($string, \%options);
762 |  |  |  |  |
763 |  |  |  |  | If you don't know if a string contains YAML or JSON, this method will use
764 |  |  |  |  | L<Parse::CPAN::Meta> to guess. In other respects it is identical to
765 |  |  |  |  | C<load_file()>.
766 |  |  |  |  |
767 |  |  |  |  | =head2 save
768 |  |  |  |  |
769 |  |  |  |  | $meta->save($distmeta_file, \%options);
770 |  |  |  |  |
771 |  |  |  |  | Serializes the object as JSON and writes it to the given file. The only valid
772 |  |  |  |  | option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
773 |  |  |  |  | is saved with UTF-8 encoding.
774 |  |  |  |  |
775 |  |  |  |  | For C<version> 2 (or higher), the filename should end in '.json'. L<JSON::PP>
776 |  |  |  |  | is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
777 |  |  |  |  | later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
778 |  |  |  |  | backend like L<JSON::XS>.
779 |  |  |  |  |
780 |  |  |  |  | For C<version> less than 2, the filename should end in '.yml'.
781 |  |  |  |  | L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
782 |  |  |  |  | is serialized to YAML. CPAN::Meta::YAML is the default YAML backend. You may
783 |  |  |  |  | set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
784 |  |  |  |  | this is not recommended due to subtle incompatibilities between YAML parsers on
785 |  |  |  |  | CPAN.
786 |  |  |  |  |
787 |  |  |  |  | =head2 meta_spec_version
788 |  |  |  |  |
789 |  |  |  |  | This method returns the version part of the C<meta_spec> entry in the distmeta
790 |  |  |  |  | structure. It is equivalent to:
791 |  |  |  |  |
792 |  |  |  |  | $meta->meta_spec->{version};
793 |  |  |  |  |
794 |  |  |  |  | =head2 effective_prereqs
795 |  |  |  |  |
796 |  |  |  |  | my $prereqs = $meta->effective_prereqs;
797 |  |  |  |  |
798 |  |  |  |  | my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
799 |  |  |  |  |
800 |  |  |  |  | This method returns a L<CPAN::Meta::Prereqs> object describing all the
801 |  |  |  |  | prereqs for the distribution. If an arrayref of feature identifiers is given,
802 |  |  |  |  | the prereqs for the identified features are merged together with the
803 |  |  |  |  | distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
804 |  |  |  |  |
805 |  |  |  |  | =head2 should_index_file
806 |  |  |  |  |
807 |  |  |  |  | ... if $meta->should_index_file( $filename );
808 |  |  |  |  |
809 |  |  |  |  | This method returns true if the given file should be indexed. It decides this
810 |  |  |  |  | by checking the C<file> and C<directory> keys in the C<no_index> property of
811 |  |  |  |  | the distmeta structure. Note that neither the version format nor
812 |  |  |  |  | C<release_status> are considered.
813 |  |  |  |  |
814 |  |  |  |  | C<$filename> should be given in unix format.
815 |  |  |  |  |
816 |  |  |  |  | =head2 should_index_package
817 |  |  |  |  |
818 |  |  |  |  | ... if $meta->should_index_package( $package );
819 |  |  |  |  |
820 |  |  |  |  | This method returns true if the given package should be indexed. It decides
821 |  |  |  |  | this by checking the C<package> and C<namespace> keys in the C<no_index>
822 |  |  |  |  | property of the distmeta structure. Note that neither the version format nor
823 |  |  |  |  | C<release_status> are considered.
824 |  |  |  |  |
825 |  |  |  |  | =head2 features
826 |  |  |  |  |
827 |  |  |  |  | my @feature_objects = $meta->features;
828 |  |  |  |  |
829 |  |  |  |  | This method returns a list of L<CPAN::Meta::Feature> objects, one for each
830 |  |  |  |  | optional feature described by the distribution's metadata.
831 |  |  |  |  |
832 |  |  |  |  | =head2 feature
833 |  |  |  |  |
834 |  |  |  |  | my $feature_object = $meta->feature( $identifier );
835 |  |  |  |  |
836 |  |  |  |  | This method returns a L<CPAN::Meta::Feature> object for the optional feature
837 |  |  |  |  | with the given identifier. If no feature with that identifier exists, an
838 |  |  |  |  | exception will be raised.
839 |  |  |  |  |
840 |  |  |  |  | =head2 as_struct
841 |  |  |  |  |
842 |  |  |  |  | my $copy = $meta->as_struct( \%options );
843 |  |  |  |  |
844 |  |  |  |  | This method returns a deep copy of the object's metadata as an unblessed hash
845 |  |  |  |  | reference. It takes an optional hashref of options. If the hashref contains
846 |  |  |  |  | a C<version> argument, the copied metadata will be converted to the version
847 |  |  |  |  | of the specification and returned. For example:
848 |  |  |  |  |
849 |  |  |  |  | my $old_spec = $meta->as_struct( {version => "1.4"} );
850 |  |  |  |  |
851 |  |  |  |  | =head2 as_string
852 |  |  |  |  |
853 |  |  |  |  | my $string = $meta->as_string( \%options );
854 |  |  |  |  |
855 |  |  |  |  | This method returns a serialized copy of the object's metadata as a character
856 |  |  |  |  | string. (The strings are B<not> UTF-8 encoded.) It takes an optional hashref
857 |  |  |  |  | of options. If the hashref contains a C<version> argument, the copied metadata
858 |  |  |  |  | will be converted to the version of the specification and returned. For
859 |  |  |  |  | example:
860 |  |  |  |  |
861 |  |  |  |  | my $string = $meta->as_string( {version => "1.4"} );
862 |  |  |  |  |
863 |  |  |  |  | For C<version> greater than or equal to 2, the string will be serialized as
864 |  |  |  |  | JSON. For C<version> less than 2, the string will be serialized as YAML. In
865 |  |  |  |  | both cases, the same rules are followed as in the C<save()> method for choosing
866 |  |  |  |  | a serialization backend.
867 |  |  |  |  |
868 |  |  |  |  | The serialized structure will include a C<x_serialization_backend> entry giving
869 |  |  |  |  | the package and version used to serialize. Any existing key in the given
870 |  |  |  |  | C<$meta> object will be clobbered.
871 |  |  |  |  |
872 |  |  |  |  | =head1 STRING DATA
873 |  |  |  |  |
874 |  |  |  |  | The following methods return a single value, which is the value for the
875 |  |  |  |  | corresponding entry in the distmeta structure. Values should be either undef
876 |  |  |  |  | or strings.
877 |  |  |  |  |
878 |  |  |  |  | =over 4
879 |  |  |  |  |
880 |  |  |  |  | =item *
881 |  |  |  |  |
882 |  |  |  |  | abstract
883 |  |  |  |  |
884 |  |  |  |  | =item *
885 |  |  |  |  |
886 |  |  |  |  | description
887 |  |  |  |  |
888 |  |  |  |  | =item *
889 |  |  |  |  |
890 |  |  |  |  | dynamic_config
891 |  |  |  |  |
892 |  |  |  |  | =item *
893 |  |  |  |  |
894 |  |  |  |  | generated_by
895 |  |  |  |  |
896 |  |  |  |  | =item *
897 |  |  |  |  |
898 |  |  |  |  | name
899 |  |  |  |  |
900 |  |  |  |  | =item *
901 |  |  |  |  |
902 |  |  |  |  | release_status
903 |  |  |  |  |
904 |  |  |  |  | =item *
905 |  |  |  |  |
906 |  |  |  |  | version
907 |  |  |  |  |
908 |  |  |  |  | =back
909 |  |  |  |  |
910 |  |  |  |  | =head1 LIST DATA
911 |  |  |  |  |
912 |  |  |  |  | These methods return lists of string values, which might be represented in the
913 |  |  |  |  | distmeta structure as arrayrefs or scalars:
914 |  |  |  |  |
915 |  |  |  |  | =over 4
916 |  |  |  |  |
917 |  |  |  |  | =item *
918 |  |  |  |  |
919 |  |  |  |  | authors
920 |  |  |  |  |
921 |  |  |  |  | =item *
922 |  |  |  |  |
923 |  |  |  |  | keywords
924 |  |  |  |  |
925 |  |  |  |  | =item *
926 |  |  |  |  |
927 |  |  |  |  | licenses
928 |  |  |  |  |
929 |  |  |  |  | =back
930 |  |  |  |  |
931 |  |  |  |  | The C<authors> and C<licenses> methods may also be called as C<author> and
932 |  |  |  |  | C<license>, respectively, to match the field name in the distmeta structure.
933 |  |  |  |  |
934 |  |  |  |  | =head1 MAP DATA
935 |  |  |  |  |
936 |  |  |  |  | These readers return hashrefs of arbitrary unblessed data structures, each
937 |  |  |  |  | described more fully in the specification:
938 |  |  |  |  |
939 |  |  |  |  | =over 4
940 |  |  |  |  |
941 |  |  |  |  | =item *
942 |  |  |  |  |
943 |  |  |  |  | meta_spec
944 |  |  |  |  |
945 |  |  |  |  | =item *
946 |  |  |  |  |
947 |  |  |  |  | resources
948 |  |  |  |  |
949 |  |  |  |  | =item *
950 |  |  |  |  |
951 |  |  |  |  | provides
952 |  |  |  |  |
953 |  |  |  |  | =item *
954 |  |  |  |  |
955 |  |  |  |  | no_index
956 |  |  |  |  |
957 |  |  |  |  | =item *
958 |  |  |  |  |
959 |  |  |  |  | prereqs
960 |  |  |  |  |
961 |  |  |  |  | =item *
962 |  |  |  |  |
963 |  |  |  |  | optional_features
964 |  |  |  |  |
965 |  |  |  |  | =back
966 |  |  |  |  |
967 |  |  |  |  | =head1 CUSTOM DATA
968 |  |  |  |  |
969 |  |  |  |  | A list of custom keys are available from the C<custom_keys> method and
970 |  |  |  |  | particular keys may be retrieved with the C<custom> method.
971 |  |  |  |  |
972 |  |  |  |  | say $meta->custom($_) for $meta->custom_keys;
973 |  |  |  |  |
974 |  |  |  |  | If a custom key refers to a data structure, a deep clone is returned.
975 |  |  |  |  |
976 |  |  |  |  | =for Pod::Coverage TO_JSON abstract author authors custom custom_keys description dynamic_config
977 |  |  |  |  | generated_by keywords license licenses meta_spec name no_index
978 |  |  |  |  | optional_features prereqs provides release_status resources version
979 |  |  |  |  |
980 |  |  |  |  | =head1 BUGS
981 |  |  |  |  |
982 |  |  |  |  | Please report any bugs or feature using the CPAN Request Tracker.
983 |  |  |  |  | Bugs can be submitted through the web interface at
984 |  |  |  |  | L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
985 |  |  |  |  |
986 |  |  |  |  | When submitting a bug or request, please include a test-file or a patch to an
987 |  |  |  |  | existing test-file that illustrates the bug or desired feature.
988 |  |  |  |  |
989 |  |  |  |  | =head1 SEE ALSO
990 |  |  |  |  |
991 |  |  |  |  | =over 4
992 |  |  |  |  |
993 |  |  |  |  | =item *
994 |  |  |  |  |
995 |  |  |  |  | L<CPAN::Meta::Converter>
996 |  |  |  |  |
997 |  |  |  |  | =item *
998 |  |  |  |  |
999 |  |  |  |  | L<CPAN::Meta::Validator>
1000 |  |  |  |  |
1001 |  |  |  |  | =back
1002 |  |  |  |  |
1003 |  |  |  |  | =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
1004 |  |  |  |  |
1005 |  |  |  |  | =head1 SUPPORT
1006 |  |  |  |  |
1007 |  |  |  |  | =head2 Bugs / Feature Requests
1008 |  |  |  |  |
1009 |  |  |  |  | Please report any bugs or feature requests through the issue tracker
1010 |  |  |  |  | at L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues>.
1011 |  |  |  |  | You will be notified automatically of any progress on your issue.
1012 |  |  |  |  |
1013 |  |  |  |  | =head2 Source Code
1014 |  |  |  |  |
1015 |  |  |  |  | This is open source software. The code repository is available for
1016 |  |  |  |  | public review and contribution under the terms of the license.
1017 |  |  |  |  |
1018 |  |  |  |  | L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta>
1019 |  |  |  |  |
1020 |  |  |  |  | git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git
1021 |  |  |  |  |
1022 |  |  |  |  | =head1 AUTHORS
1023 |  |  |  |  |
1024 |  |  |  |  | =over 4
1025 |  |  |  |  |
1026 |  |  |  |  | =item *
1027 |  |  |  |  |
1028 |  |  |  |  | David Golden <dagolden@cpan.org>
1029 |  |  |  |  |
1030 |  |  |  |  | =item *
1031 |  |  |  |  |
1032 |  |  |  |  | Ricardo Signes <rjbs@cpan.org>
1033 |  |  |  |  |
1034 |  |  |  |  | =item *
1035 |  |  |  |  |
1036 |  |  |  |  | Adam Kennedy <adamk@cpan.org>
1037 |  |  |  |  |
1038 |  |  |  |  | =back
1039 |  |  |  |  |
1040 |  |  |  |  | =head1 CONTRIBUTORS
1041 |  |  |  |  |
1042 |  |  |  |  | =for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Benjamin Noggle Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov David Golden Eric Wilhelm Graham Knop Gregor Hermann Karen Etheridge Kenichi Ishigaki Kent Fredric Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern Mohammad Anwar mohawk2 moznion Niko Tyni Olaf Alders Olivier Mengué Randy Sims Tomohiro Hosaka
1043 |  |  |  |  |
1044 |  |  |  |  | =over 4
1045 |  |  |  |  |
1046 |  |  |  |  | =item *
1047 |  |  |  |  |
1048 |  |  |  |  | Ansgar Burchardt <ansgar@cpan.org>
1049 |  |  |  |  |
1050 |  |  |  |  | =item *
1051 |  |  |  |  |
1052 |  |  |  |  | Avar Arnfjord Bjarmason <avar@cpan.org>
1053 |  |  |  |  |
1054 |  |  |  |  | =item *
1055 |  |  |  |  |
1056 |  |  |  |  | Benjamin Noggle <agwind@users.noreply.github.com>
1057 |  |  |  |  |
1058 |  |  |  |  | =item *
1059 |  |  |  |  |
1060 |  |  |  |  | Christopher J. Madsen <cjm@cpan.org>
1061 |  |  |  |  |
1062 |  |  |  |  | =item *
1063 |  |  |  |  |
1064 |  |  |  |  | Chuck Adams <cja987@gmail.com>
1065 |  |  |  |  |
1066 |  |  |  |  | =item *
1067 |  |  |  |  |
1068 |  |  |  |  | Cory G Watson <gphat@cpan.org>
1069 |  |  |  |  |
1070 |  |  |  |  | =item *
1071 |  |  |  |  |
1072 |  |  |  |  | Damyan Ivanov <dam@cpan.org>
1073 |  |  |  |  |
1074 |  |  |  |  | =item *
1075 |  |  |  |  |
1076 |  |  |  |  | David Golden <xdg@xdg.me>
1077 |  |  |  |  |
1078 |  |  |  |  | =item *
1079 |  |  |  |  |
1080 |  |  |  |  | Eric Wilhelm <ewilhelm@cpan.org>
1081 |  |  |  |  |
1082 |  |  |  |  | =item *
1083 |  |  |  |  |
1084 |  |  |  |  | Graham Knop <haarg@haarg.org>
1085 |  |  |  |  |
1086 |  |  |  |  | =item *
1087 |  |  |  |  |
1088 |  |  |  |  | Gregor Hermann <gregoa@debian.org>
1089 |  |  |  |  |
1090 |  |  |  |  | =item *
1091 |  |  |  |  |
1092 |  |  |  |  | Karen Etheridge <ether@cpan.org>
1093 |  |  |  |  |
1094 |  |  |  |  | =item *
1095 |  |  |  |  |
1096 |  |  |  |  | Kenichi Ishigaki <ishigaki@cpan.org>
1097 |  |  |  |  |
1098 |  |  |  |  | =item *
1099 |  |  |  |  |
1100 |  |  |  |  | Kent Fredric <kentfredric@gmail.com>
1101 |  |  |  |  |
1102 |  |  |  |  | =item *
1103 |  |  |  |  |
1104 |  |  |  |  | Ken Williams <kwilliams@cpan.org>
1105 |  |  |  |  |
1106 |  |  |  |  | =item *
1107 |  |  |  |  |
1108 |  |  |  |  | Lars Dieckow <daxim@cpan.org>
1109 |  |  |  |  |
1110 |  |  |  |  | =item *
1111 |  |  |  |  |
1112 |  |  |  |  | Leon Timmermans <leont@cpan.org>
1113 |  |  |  |  |
1114 |  |  |  |  | =item *
1115 |  |  |  |  |
1116 |  |  |  |  | majensen <maj@fortinbras.us>
1117 |  |  |  |  |
1118 |  |  |  |  | =item *
1119 |  |  |  |  |
1120 |  |  |  |  | Mark Fowler <markf@cpan.org>
1121 |  |  |  |  |
1122 |  |  |  |  | =item *
1123 |  |  |  |  |
1124 |  |  |  |  | Matt S Trout <mst@shadowcat.co.uk>
1125 |  |  |  |  |
1126 |  |  |  |  | =item *
1127 |  |  |  |  |
1128 |  |  |  |  | Michael G. Schwern <mschwern@cpan.org>
1129 |  |  |  |  |
1130 |  |  |  |  | =item *
1131 |  |  |  |  |
1132 |  |  |  |  | Mohammad S Anwar <mohammad.anwar@yahoo.com>
1133 |  |  |  |  |
1134 |  |  |  |  | =item *
1135 |  |  |  |  |
1136 |  |  |  |  | mohawk2 <mohawk2@users.noreply.github.com>
1137 |  |  |  |  |
1138 |  |  |  |  | =item *
1139 |  |  |  |  |
1140 |  |  |  |  | moznion <moznion@gmail.com>
1141 |  |  |  |  |
1142 |  |  |  |  | =item *
1143 |  |  |  |  |
1144 |  |  |  |  | Niko Tyni <ntyni@debian.org>
1145 |  |  |  |  |
1146 |  |  |  |  | =item *
1147 |  |  |  |  |
1148 |  |  |  |  | Olaf Alders <olaf@wundersolutions.com>
1149 |  |  |  |  |
1150 |  |  |  |  | =item *
1151 |  |  |  |  |
1152 |  |  |  |  | Olivier Mengué <dolmen@cpan.org>
1153 |  |  |  |  |
1154 |  |  |  |  | =item *
1155 |  |  |  |  |
1156 |  |  |  |  | Randy Sims <randys@thepierianspring.org>
1157 |  |  |  |  |
1158 |  |  |  |  | =item *
1159 |  |  |  |  |
1160 |  |  |  |  | Tomohiro Hosaka <bokutin@bokut.in>
1161 |  |  |  |  |
1162 |  |  |  |  | =back
1163 |  |  |  |  |
1164 |  |  |  |  | =head1 COPYRIGHT AND LICENSE
1165 |  |  |  |  |
1166 |  |  |  |  | This software is copyright (c) 2010 by David Golden, Ricardo Signes, Adam Kennedy and Contributors.
1167 |  |  |  |  |
1168 |  |  |  |  | This is free software; you can redistribute it and/or modify it under
1169 |  |  |  |  | the same terms as the Perl 5 programming language system itself.
1170 |  |  |  |  |
1171 |  |  |  |  | =cut
1172 |  |  |  |  |
1173 |  |  |  |  | __END__
|  |  |  |  | # spent 3µs within CPAN::Meta::CORE:subst which was called 6 times, avg 450ns/call: # 6 times (3µs+0s) by CPAN::Meta::BEGIN@151 at line 164, avg 450ns/call sub CPAN::Meta::CORE:subst; # opcode
|  |  |  |  | # spent 1µs within CPAN::Meta::__ANON__ which was called 4 times, avg 275ns/call: # once (400ns+0s) by CPAN::Meta::BEGIN@57 at line 57 # once (300ns+0s) by CPAN::Meta::BEGIN@59 at line 59 # once (200ns+0s) by CPAN::Meta::BEGIN@58 at line 58 # once (200ns+0s) by CPAN::Meta::BEGIN@60 at line 60 sub CPAN::Meta::__ANON__; # xsub
|  |  |  |  | # spent 8µs within main::CORE:say which was called: # once (8µs+0s) by main::RUNTIME at line 6 of /home/leont/Code/cpan/experimental/test.pl sub main::CORE:say; # opcode
|  |  |  |  | # spent 500ns within main::__ANON__ which was called: # once (500ns+0s) by main::BEGIN@4 at line 4 of /home/leont/Code/cpan/experimental/test.pl sub main::__ANON__; # xsub