File Coverage

blib/lib/MRP/Introspection.pm
Criterion Covered Total %
statement 44 129 34.1
branch 10 50 20.0
condition 5 30 16.6
subroutine 10 20 50.0
pod 7 14 50.0
total 76 243 31.2


line stmt bran cond sub pod time code
1             package MRP::Introspection;
2              
3 1     1   6 use strict;
  1         1  
  1         107  
4 1     1   5 use Exporter;
  1         2  
  1         168  
5              
6 1     1   5 use vars qw(@ISA @EXPORT_OK %EXPORT_TAGS $VERSION);
  1         2  
  1         174  
7              
8             $VERSION = 1.0;
9              
10             @EXPORT_OK = qw (functions function functionsMatching
11             scalars scalar
12             arrays array
13             hashes hash
14             recursiveFunction recursiveInheritance ISA);
15             %EXPORT_TAGS = ( ALL => [@EXPORT_OK] );
16              
17             @ISA = qw (Exporter);
18              
19             sub symTable ( $ ) {
20 57     57 1 66 my ($package) = shift;
21 57   33     191 $package = (ref $package || $package) . '::';
22 1     1   5 no strict 'refs';
  1         1  
  1         760  
23 57         738 return \%$package;
24             }
25            
26             sub ISA ( $ ) {
27 2     2 1 24 my $thingy = shift;
28 2         6 my $isa = array($thingy, 'ISA', @_);
29 2 50       6 return () unless defined $isa;
30 2 0       18 (wantarray) ?
    50          
31             (defined $isa) ? return @$isa : return () :
32             return $isa;
33             }
34              
35             sub functions( $ ) {
36 2     2 1 3 my $thingy = shift;
37 2         3 my %funcs;
38 2         3 my ($name, $glob);
39              
40 2         3 while(($name, $glob) = each %{symTable $thingy}) {
  57         93  
41 55 100       578 defined (*$glob{CODE}) && do { $funcs{$name} = \&$glob };
  30         167  
42             }
43              
44 2         27 return %funcs;
45             }
46              
47             sub functionsMatching( $$ ) {
48 0     0 1 0 my ($thingy,$pattern)=@_;
49 0         0 my %funcs;
50 0         0 my ($name, $glob);
51              
52 0         0 while(($name, $glob) = each %{symTable $thingy}) {
  0         0  
53             $name =~ /^$pattern$/ &&
54 0 0 0     0 defined (*$glob{CODE}) && do { $funcs{$name} = \&$glob };
  0         0  
55             }
56 0         0 return %funcs;
57             }
58              
59             sub scalars( $ ) {
60 0     0 0 0 my $thingy = shift;
61 0         0 my %scalars;
62 0         0 my ($name, $glob);
63              
64 0         0 while(($name, $glob) = each %{symTable $thingy}) {
  0         0  
65 0 0       0 defined ${*$glob{SCALAR}} && do { $scalars{$name} = \$$glob };
  0         0  
  0         0  
66             }
67 0 0       0 (wantarray) ?
68             return %scalars :
69             return \%scalars;
70             }
71              
72             sub arrays( $ ) {
73 0     0 0 0 my $thingy = shift;
74 0         0 my %arrays;
75 0         0 my ($name, $glob);
76              
77 0         0 while(($name, $glob) = each %{symTable $thingy}) {
  0         0  
78 0 0       0 defined (*$glob{ARRAY}) && do { $arrays{$name} = \@$glob };
  0         0  
79             }
80             (wantarray)
81 0 0       0 ? return %arrays
82             : return \%arrays;
83             }
84              
85             sub hashes( $ ) {
86 0     0 0 0 my $thingy = shift;
87 0         0 my %hashes;
88 0         0 my ($name, $glob);
89              
90 0         0 while(($name, $glob) = each %{symTable $thingy}) {
  0         0  
91 0 0       0 $name =~ /::$/ && next; # don't return nested symbol tables
92 0 0       0 defined (*$glob{HASH}) && do { $hashes{$name} = \%$glob };
  0         0  
93             }
94 0 0       0 (wantarray) ?
95             return %hashes :
96             return \%hashes;
97             }
98              
99 1     1   7 no strict 'refs';
  1         2  
  1         1094  
100              
101             sub function($$;$) {
102 0     0 0 0 my ($thingy,$sym,$val) = @_;
103 0   0     0 my $fullName = join '::', ref $thingy || $thingy, $sym;
104 0 0       0 *{$fullName} = $_[2] if(@_ == 3);
  0         0  
105 0         0 return *{$fullName}{CODE};
  0         0  
106             }
107              
108             sub scalar ( $$;$ ) {
109 0     0 0 0 my ($thingy,$sym,$val) = @_;
110 0   0     0 my $fullName = join '::', ref $thingy || $thingy, $sym;
111 0 0       0 ${$fullName} = $_[2] if(@_ == 3);
  0         0  
112 0         0 return *{$fullName}{SCALAR};
  0         0  
113             }
114              
115             sub array ( $$;@ ) {
116 6     6 0 19 my ($thingy,$sym) = (shift,shift);
117 6   33     29 my $fullName = join '::', ref $thingy || $thingy, $sym;
118 6 50 33     40 @{$fullName} = @_ if(@_ or not defined wantarray);
  0         0  
119 6         6 my $ref = *{$fullName}{ARRAY};
  6         32  
120 6 100       14 if($ref) {
121             return (wantarray)
122 2 50       8 ? @$ref
123             : $ref;
124             }
125 4         27 return;
126             }
127              
128             sub hash ( $$;@ ) {
129 6     6 0 12 my ($thingy,$sym) = (shift,shift);
130 6   33     35 my $fullName = join '::', ref $thingy || $thingy, $sym;
131 6 50 33     38 %{$fullName} = @_ if(@_ or not defined wantarray);
  0         0  
132 6         7 my $ref = *{$fullName}{HASH};
  6         32  
133             return (wantarray)
134 6 50       32 ? %$ref
135             : $ref;
136             }
137              
138             sub recursiveFunction ( $$;@ ) {
139 0     0 1   my ($thingy,$function) = (shift,shift);
140 0   0       my $package = ref $thingy || $thingy;
141 0           my %functions = $thingy->$function(@_);
142 0           my %return;
143 0           my ($key,$val);
144 0           my @ISA = $thingy->ISA;
145 0           while(($key, $val) = each %functions) {
146 0           $return{join '::',$package,$key} = $val;
147             }
148            
149 0           %return = map { recursiveFunction $_, $function, @_ } @ISA;
  0            
150            
151 0 0         (wantarray) ?
152             return %return :
153             return \%return;
154             }
155              
156             sub recursiveInheritance ( $$;@ ) {
157 0     0 1   my ($thingy,$function) = (shift,shift);
158 0   0       my $package = ref $thingy || $thingy;
159 0           my %functions = $thingy->$function(@_);
160 0           my %return;
161 0           my ($key,$val);
162 0           while(($key, $val) = each %functions) {
163 0           $return{join '::',$package,$key} = $val;
164             }
165              
166 0           foreach my $isa (ISA($thingy)) {
167 0           my %parentFuncs = recursiveInheritance($isa, $function, @_);
168 0           foreach my $name (keys %parentFuncs) {
169 0           my ($fname) = $name =~ /([^:]+)$/;
170 0 0         $return{$name} = $parentFuncs{$name} unless exists $functions{$fname};
171             }
172             }
173              
174 0 0         (wantarray) ?
175             return %return :
176             return \%return;
177             }
178              
179             sub superAUTOLOAD ( $$@ ) {
180 0     0 1   my ($thingy,$value) = (shift,shift);
181 0           my ($func,$name);
182 0           foreach(ISA($thingy)) {
183 0           $func = _setAUTOLOAD($_,$value);
184 0 0         return $func if $func;
185             }
186             }
187              
188             sub _setAUTOLOAD ( $$ ) {
189 0     0     my ($thingy,$value) = (@_);
190 0           my ($func);
191 0 0         if($func = function($thingy,'AUTOLOAD')) {
192 0           MRP::Introspection::scalar($thingy,'AUTOLOAD',$value);
193 0           return $func;
194             }
195              
196 0           foreach(ISA($thingy)) {
197 0 0         $func = _setAUTOLOAD($_,$value) and last;
198             }
199              
200 0           return $func;
201             }
202              
203             $VERSION;
204              
205             __END__