File Coverage

blib/lib/SHARYANTO/Package/Util.pm
Criterion Covered Total %
statement 65 67 97.0
branch 22 30 73.3
condition 8 13 61.5
subroutine 9 9 100.0
pod 3 3 100.0
total 107 122 87.7


line stmt bran cond sub pod time code
1             package SHARYANTO::Package::Util;
2              
3 1     1   706 use 5.010001;
  1         3  
  1         40  
4 1     1   5 use strict;
  1         2  
  1         27  
5 1     1   5 use warnings;
  1         1  
  1         153  
6              
7             require Exporter;
8             our @ISA = qw(Exporter);
9             our @EXPORT_OK = qw(
10             package_exists
11             list_package_contents
12             list_subpackages
13             );
14              
15             our $VERSION = '0.56'; # VERSION
16              
17             sub package_exists {
18 1     1   6 no strict 'refs';
  1         2  
  1         233  
19              
20 10     10 1 23756 my $pkg = shift;
21              
22 10 50       62 return unless $pkg =~ /\A\w+(::\w+)*\z/;
23 10 100       35 if ($pkg =~ s/::(\w+)\z//) {
24 3         7 return !!${$pkg . "::"}{$1 . "::"};
  3         24  
25             } else {
26 7         55 return !!$::{$pkg . "::"};
27             }
28             }
29              
30             # XXX incomplete/improper
31             sub list_package_contents {
32 1     1   6 no strict 'refs';
  1         2  
  1         391  
33              
34 1     1 1 2 my $pkg = shift;
35              
36 1 50 33     8 return () unless !length($pkg) || package_exists($pkg);
37 1         3 my $symtbl = \%{$pkg . "::"};
  1         5  
38              
39 1         3 my %res;
40 1         10 while (my ($k, $v) = each %$symtbl) {
41 2 50       6 next if $k =~ /::$/; # subpackage
42 2         3 my $n;
43 2 50       14 if ("$v" !~ /^\*/) {
44             # constant
45 0         0 $res{$k} = $v;
46 0         0 next;
47             }
48 2 100       10 if (defined *$v{CODE}) {
49 1         4 $res{$k} = *$v{CODE}; # subroutine
50 1         2 $n++;
51             }
52 2 100       9 if (defined *$v{HASH}) {
53 1         2 $res{"\%$k"} = \%{*$v}; # hash
  1         5  
54 1         3 $n++;
55             }
56 2 100       7 if (defined *$v{ARRAY}) {
57 1         2 $res{"\@$k"} = \@{*$v}; # array
  1         5  
58 1         2 $n++;
59             }
60 2 100 66     9 if (defined(*$v{SCALAR}) # XXX always defined?
  2         9  
61             && defined(${*$v})) { # currently we filter undef values
62 1         2 $res{"\$$k"} = \${*$v}; # scalar
  1         5  
63 1         2 $n++;
64             }
65              
66 2 100       11 if (!$n) {
67 1         6 $res{"\*$k"} = $v; # glob
68             }
69             }
70              
71 1         25 %res;
72             }
73              
74             sub list_subpackages {
75 1     1   6 no strict 'refs';
  1         2  
  1         280  
76              
77 5     5 1 796 my ($pkg, $recursive, $cur_res, $ref_mem) = @_;
78              
79 5 50 33     21 return () unless !length($pkg) || package_exists($pkg);
80              
81             # this is used to avoid deep recursion. for example (the only one?) %:: and
82             # %main:: point to the same thing.
83 5   100     20 $ref_mem //= {};
84              
85 5         6 my $symtbl = \%{$pkg . "::"};
  5         17  
86 5 50       21 return () if $ref_mem->{"$symtbl"}++;
87              
88 5   100     19 my $res = $cur_res // [];
89 5         16 for (sort keys %$symtbl) {
90 4 50       22 next unless s/::$//;
91 4 50       16 my $name = (length($pkg) ? "$pkg\::" : "" ) . $_;
92 4         7 push @$res, $name;
93 4 100       23 list_subpackages($name, 1, $res, $ref_mem) if $recursive;
94             }
95              
96 5         36 @$res;
97             }
98              
99             1;
100             # ABSTRACT: Package-related utilities
101              
102             __END__