Profile of Parse/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/Parse/CPAN/Meta.pm
Statements | Executed 16 statements in 546µs

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
1 | 1 | 1 | 7µs | 7µs | CPAN::Meta::Converter::::BEGIN@1.6CPAN::Meta::Converter::BEGIN@1.6
1 | 1 | 1 | 4µs | 9µs | Parse::CPAN::Meta::::BEGIN@47 Parse::CPAN::Meta::BEGIN@47
1 | 1 | 1 | 3µs | 13µs | Parse::CPAN::Meta::::BEGIN@10 Parse::CPAN::Meta::BEGIN@10
1 | 1 | 1 | 3µs | 11µs | Parse::CPAN::Meta::::BEGIN@9 Parse::CPAN::Meta::BEGIN@9
1 | 1 | 1 | 3µs | 4µs | CPAN::Meta::Converter::::BEGIN@2.7CPAN::Meta::Converter::BEGIN@2.7
1 | 1 | 1 | 3µs | 10µs | CPAN::Meta::Converter::::BEGIN@3.8CPAN::Meta::Converter::BEGIN@3.8
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::Load Parse::CPAN::Meta::Load
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::LoadFile Parse::CPAN::Meta::LoadFile
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::_can_load Parse::CPAN::Meta::_can_load
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::_slurp Parse::CPAN::Meta::_slurp
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::json_backend Parse::CPAN::Meta::json_backend
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::json_decoder Parse::CPAN::Meta::json_decoder
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::load_file Parse::CPAN::Meta::load_file
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::load_json_string Parse::CPAN::Meta::load_json_string
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::load_string Parse::CPAN::Meta::load_string
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::load_yaml_string Parse::CPAN::Meta::load_yaml_string
0 | 0 | 0 | 0s | 0s | Parse::CPAN::Meta::::yaml_backend Parse::CPAN::Meta::yaml_backend

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 CPAN::Meta::Converter::BEGIN@1.6 which was called: # once (7µs+0s) by CPAN::Meta::Converter::BEGIN@28 at line 1 use 5.008001; # spent 7µs making 1 call to CPAN::Meta::Converter::BEGIN@1.6
2 | 2 | 9µs | 2 | 6µs | # spent 4µs (3+1) within CPAN::Meta::Converter::BEGIN@2.7 which was called: # once (3µs+1µs) by CPAN::Meta::Converter::BEGIN@28 at line 2 use strict; # spent 4µs making 1 call to CPAN::Meta::Converter::BEGIN@2.7 # spent 1µs making 1 call to strict::import
3 | 2 | 20µs | 2 | 18µs | # spent 10µs (3+8) within CPAN::Meta::Converter::BEGIN@3.8 which was called: # once (3µs+8µs) by CPAN::Meta::Converter::BEGIN@28 at line 3 use warnings; # spent 10µs making 1 call to CPAN::Meta::Converter::BEGIN@3.8 # spent 8µs making 1 call to warnings::import
4 |  |  |  |  | package Parse::CPAN::Meta;
5 |  |  |  |  | # ABSTRACT: Parse META.yml and META.json CPAN metadata files
6 |  |  |  |  |
7 | 1 | 200ns |  |  | our $VERSION = '2.150010';
8 |  |  |  |  |
9 | 2 | 11µs | 2 | 19µs | # spent 11µs (3+8) within Parse::CPAN::Meta::BEGIN@9 which was called: # once (3µs+8µs) by CPAN::Meta::Converter::BEGIN@28 at line 9 use Exporter; # spent 11µs making 1 call to Parse::CPAN::Meta::BEGIN@9 # spent 8µs making 1 call to Exporter::import
10 | 2 | 132µs | 2 | 24µs | # spent 13µs (3+10) within Parse::CPAN::Meta::BEGIN@10 which was called: # once (3µs+10µs) by CPAN::Meta::Converter::BEGIN@28 at line 10 use Carp 'croak'; # spent 13µs making 1 call to Parse::CPAN::Meta::BEGIN@10 # spent 10µs making 1 call to Exporter::import
11 |  |  |  |  |
12 | 1 | 3µs |  |  | our @ISA = qw/Exporter/;
13 | 1 | 300ns |  |  | our @EXPORT_OK = qw/Load LoadFile/;
14 |  |  |  |  |
15 |  |  |  |  | sub load_file {
16 |  |  |  |  | my ($class, $filename) = @_;
17 |  |  |  |  |
18 |  |  |  |  | my $meta = _slurp($filename);
19 |  |  |  |  |
20 |  |  |  |  | if ($filename =~ /\.ya?ml$/) {
21 |  |  |  |  | return $class->load_yaml_string($meta);
22 |  |  |  |  | }
23 |  |  |  |  | elsif ($filename =~ /\.json$/) {
24 |  |  |  |  | return $class->load_json_string($meta);
25 |  |  |  |  | }
26 |  |  |  |  | else {
27 |  |  |  |  | $class->load_string($meta); # try to detect yaml/json
28 |  |  |  |  | }
29 |  |  |  |  | }
30 |  |  |  |  |
31 |  |  |  |  | sub load_string {
32 |  |  |  |  | my ($class, $string) = @_;
33 |  |  |  |  | if ( $string =~ /^---/ ) { # looks like YAML
34 |  |  |  |  | return $class->load_yaml_string($string);
35 |  |  |  |  | }
36 |  |  |  |  | elsif ( $string =~ /^\s*\{/ ) { # looks like JSON
37 |  |  |  |  | return $class->load_json_string($string);
38 |  |  |  |  | }
39 |  |  |  |  | else { # maybe doc-marker-free YAML
40 |  |  |  |  | return $class->load_yaml_string($string);
41 |  |  |  |  | }
42 |  |  |  |  | }
43 |  |  |  |  |
44 |  |  |  |  | sub load_yaml_string {
45 |  |  |  |  | my ($class, $string) = @_;
46 |  |  |  |  | my $backend = $class->yaml_backend();
47 | 2 | 348µs | 2 | 14µs | # spent 9µs (4+5) within Parse::CPAN::Meta::BEGIN@47 which was called: # once (4µs+5µs) by CPAN::Meta::Converter::BEGIN@28 at line 47 my $data = eval { no strict 'refs'; &{"$backend\::Load"}($string) }; # spent 9µs making 1 call to Parse::CPAN::Meta::BEGIN@47 # spent 5µs making 1 call to strict::unimport
48 |  |  |  |  | croak $@ if $@;
49 |  |  |  |  | return $data || {}; # in case document was valid but empty
50 |  |  |  |  | }
51 |  |  |  |  |
52 |  |  |  |  | sub load_json_string {
53 |  |  |  |  | my ($class, $string) = @_;
54 |  |  |  |  | require Encode;
55 |  |  |  |  | # load_json_string takes characters, decode_json expects bytes
56 |  |  |  |  | my $encoded = Encode::encode('UTF-8', $string, Encode::PERLQQ());
57 |  |  |  |  | my $data = eval { $class->json_decoder()->can('decode_json')->($encoded) };
58 |  |  |  |  | croak $@ if $@;
59 |  |  |  |  | return $data || {};
60 |  |  |  |  | }
61 |  |  |  |  |
62 |  |  |  |  | sub yaml_backend {
63 |  |  |  |  | if ($ENV{PERL_CORE} or not defined $ENV{PERL_YAML_BACKEND} ) {
64 |  |  |  |  | _can_load( 'CPAN::Meta::YAML', 0.011 )
65 |  |  |  |  | or croak "CPAN::Meta::YAML 0.011 is not available\n";
66 |  |  |  |  | return "CPAN::Meta::YAML";
67 |  |  |  |  | }
68 |  |  |  |  | else {
69 |  |  |  |  | my $backend = $ENV{PERL_YAML_BACKEND};
70 |  |  |  |  | _can_load( $backend )
71 |  |  |  |  | or croak "Could not load PERL_YAML_BACKEND '$backend'\n";
72 |  |  |  |  | $backend->can("Load")
73 |  |  |  |  | or croak "PERL_YAML_BACKEND '$backend' does not implement Load()\n";
74 |  |  |  |  | return $backend;
75 |  |  |  |  | }
76 |  |  |  |  | }
77 |  |  |  |  |
78 |  |  |  |  | sub json_decoder {
79 |  |  |  |  | if ($ENV{PERL_CORE}) {
80 |  |  |  |  | _can_load( 'JSON::PP' => 2.27300 )
81 |  |  |  |  | or croak "JSON::PP 2.27300 is not available\n";
82 |  |  |  |  | return 'JSON::PP';
83 |  |  |  |  | }
84 |  |  |  |  | if (my $decoder = $ENV{CPAN_META_JSON_DECODER}) {
85 |  |  |  |  | _can_load( $decoder )
86 |  |  |  |  | or croak "Could not load CPAN_META_JSON_DECODER '$decoder'\n";
87 |  |  |  |  | $decoder->can('decode_json')
88 |  |  |  |  | or croak "No decode_json sub provided by CPAN_META_JSON_DECODER '$decoder'\n";
89 |  |  |  |  | return $decoder;
90 |  |  |  |  | }
91 |  |  |  |  | return $_[0]->json_backend;
92 |  |  |  |  | }
93 |  |  |  |  |
94 |  |  |  |  | sub json_backend {
95 |  |  |  |  | if ($ENV{PERL_CORE}) {
96 |  |  |  |  | _can_load( 'JSON::PP' => 2.27300 )
97 |  |  |  |  | or croak "JSON::PP 2.27300 is not available\n";
98 |  |  |  |  | return 'JSON::PP';
99 |  |  |  |  | }
100 |  |  |  |  | if (my $backend = $ENV{CPAN_META_JSON_BACKEND}) {
101 |  |  |  |  | _can_load( $backend )
102 |  |  |  |  | or croak "Could not load CPAN_META_JSON_BACKEND '$backend'\n";
103 |  |  |  |  | $backend->can('new')
104 |  |  |  |  | or croak "No constructor provided by CPAN_META_JSON_BACKEND '$backend'\n";
105 |  |  |  |  | return $backend;
106 |  |  |  |  | }
107 |  |  |  |  | if (! $ENV{PERL_JSON_BACKEND} or $ENV{PERL_JSON_BACKEND} eq 'JSON::PP') {
108 |  |  |  |  | _can_load( 'JSON::PP' => 2.27300 )
109 |  |  |  |  | or croak "JSON::PP 2.27300 is not available\n";
110 |  |  |  |  | return 'JSON::PP';
111 |  |  |  |  | }
112 |  |  |  |  | else {
113 |  |  |  |  | _can_load( 'JSON' => 2.5 )
114 |  |  |  |  | or croak "JSON 2.5 is required for " .
115 |  |  |  |  | "\$ENV{PERL_JSON_BACKEND} = '$ENV{PERL_JSON_BACKEND}'\n";
116 |  |  |  |  | return "JSON";
117 |  |  |  |  | }
118 |  |  |  |  | }
119 |  |  |  |  |
120 |  |  |  |  | sub _slurp {
121 |  |  |  |  | require Encode;
122 |  |  |  |  | open my $fh, "<:raw", "$_[0]" ## no critic
123 |  |  |  |  | or die "can't open $_[0] for reading: $!";
124 |  |  |  |  | my $content = do { local $/; <$fh> };
125 |  |  |  |  | $content = Encode::decode('UTF-8', $content, Encode::PERLQQ());
126 |  |  |  |  | return $content;
127 |  |  |  |  | }
128 |  |  |  |  |
129 |  |  |  |  | sub _can_load {
130 |  |  |  |  | my ($module, $version) = @_;
131 |  |  |  |  | (my $file = $module) =~ s{::}{/}g;
132 |  |  |  |  | $file .= ".pm";
133 |  |  |  |  | return 1 if $INC{$file};
134 |  |  |  |  | return 0 if exists $INC{$file}; # prior load failed
135 |  |  |  |  | eval { require $file; 1 }
136 |  |  |  |  | or return 0;
137 |  |  |  |  | if ( defined $version ) {
138 |  |  |  |  | eval { $module->VERSION($version); 1 }
139 |  |  |  |  | or return 0;
140 |  |  |  |  | }
141 |  |  |  |  | return 1;
142 |  |  |  |  | }
143 |  |  |  |  |
144 |  |  |  |  | # Kept for backwards compatibility only
145 |  |  |  |  | # Create an object from a file
146 |  |  |  |  | sub LoadFile ($) { ## no critic
147 |  |  |  |  | return Load(_slurp(shift));
148 |  |  |  |  | }
149 |  |  |  |  |
150 |  |  |  |  | # Parse a document from a string.
151 |  |  |  |  | sub Load ($) { ## no critic
152 |  |  |  |  | require CPAN::Meta::YAML;
153 |  |  |  |  | my $object = eval { CPAN::Meta::YAML::Load(shift) };
154 |  |  |  |  | croak $@ if $@;
155 |  |  |  |  | return $object;
156 |  |  |  |  | }
157 |  |  |  |  |
158 | 1 | 2µs |  |  | 1;
159 |  |  |  |  |
160 |  |  |  |  | __END__