File Coverage

blib/lib/Method/Autoload.pm
Criterion Covered Total %
statement 55 60 91.6
branch 15 26 57.6
condition 1 3 33.3
subroutine 13 13 100.0
pod 7 7 100.0
total 91 109 83.4


line stmt bran cond sub pod time code
1             package Method::Autoload;
2 6     6   152892 use strict;
  6         14  
  6         230  
3 6     6   32 use warnings;
  6         10  
  6         162  
4 6     6   7011 use UNIVERSAL::require;
  6         13486  
  6         63  
5              
6             our $VERSION='0.02';
7             our $AUTOLOAD;
8              
9             =head1 NAME
10              
11             Method::Autoload - Autoloads methods from a list of packages into the current package
12              
13             =head1 SYNOPSIS
14              
15             package MyPackage;
16             use base qw{Method::Autoload}
17              
18             =head1 DESCRIPTION
19              
20             The Method::Autoload base class package is used to autoload methods from a list of packages where you may not know what methods are available until run time. A good use of this package is programming support for user contributed packages or user contributed plugins.
21              
22             =head1 USAGE
23              
24             use MyPackage;
25             my $object=MyPackage->new(%hash); #provides new and initialize methods
26             $object->pushPackages("My::Bar"); #appends to "packages" array
27             $object->unshiftPackages("My::Foo"); #prepends to "packages" array
28              
29             use MyPackage;
30             my $object=MyPackage->new(packages=>["My::Foo", "My::Bar"]);
31             $object->foo; #from My::Foo
32             $object->bar; #from My::Bar
33              
34             =head1 CONSTRUCTOR
35              
36             =head2 new
37              
38             my $object=MyPackage->new(%hash);
39             my $object=MyPackage->new(package=>["My::Package1", "My::Package2"]);
40              
41             =cut
42              
43             sub new {
44 6     6 1 85 my $this=shift;
45 6   33     51 my $class=ref($this) || $this;
46 6         16 my $self={};
47 6         17 bless $self, $class;
48 6         34 $self->initialize(@_);
49 6         18 return $self;
50             }
51              
52             =head2 initialize
53              
54             =cut
55              
56             sub initialize {
57 6     6 1 14 my $self=shift;
58 6         53 %$self=@_;
59             }
60              
61             =head1 METHODS PUBLIC
62              
63             =head2 packages
64              
65             Returns the current list of packages in the "packages" array.
66              
67             my @package=$object->packages; #()
68             my $package=$object->packages; #[]
69              
70             =cut
71              
72             sub packages {
73 25     25 1 754 my $self=shift;
74 25 50       90 $self->{"packages"}=[] unless ref($self->{"packages"}) eq "ARRAY";
75 25 100       184 return wantarray ? @{$self->{"packages"}} : $self->{"packages"};
  6         52  
76             }
77              
78             =head2 pushPackages
79              
80             Pushes packages on to the "packages" array.
81              
82             $object->pushPackages("My::Bar");
83             $object->pushPackages(@packages);
84              
85             =cut
86              
87             sub pushPackages {
88 1     1 1 2 my $self=shift;
89 1 50       7 push @{$self->packages}, @_ if @_;
  1         3  
90 1         4 return $self->packages;
91             }
92              
93             =head2 unshiftPackages
94              
95             Unshifts packages on to the "packages" array. Use this if you want to override a "default" package. Please use with care.
96              
97             $object->unshiftPackages("My::Foo");
98             $object->unshiftPackages(@packages);
99              
100             =cut
101              
102             sub unshiftPackages {
103 1     1 1 2 my $self=shift;
104 1 50       4 unshift @{$self->packages}, @_ if @_;
  1         3  
105 1         4 return $self->packages;
106             }
107              
108             =head2 autoloaded
109              
110             Returns a hash of autoloaded methods and the classes that they came from.
111              
112             my %hash=$object->autoloaded; #()
113             my $hash=$object->autoloaded; #{}
114              
115             =cut
116              
117             sub autoloaded {
118 10     10 1 1098 my $self=shift;
119 10 100       112 $self->{"autoloaded"}={} unless ref($self->{"autoloaded"}) eq "HASH";
120 10 50       48 return wantarray ? @{$self->{"autoloaded"}} : $self->{"autoloaded"};
  0         0  
121             }
122              
123             =head1 METHODS PRIVATE
124              
125             =head2 DESTROY ("Global" method)
126              
127             We define DESTROY in this package so that it does not call AUTOLOAD but you may overload this method in your package, if you need it.
128              
129             =cut
130              
131 8     8   3956 sub DESTROY {return "0E0"};
132              
133             =head2 AUTOLOAD ("Global" method)
134              
135             AUTOLOAD is a "global" method. Please review the limitations on inheriting this method.
136              
137             =cut
138              
139             sub AUTOLOAD {
140 6     6   4082 my $self=shift;
141 6         10 my $method=$AUTOLOAD;
142 6         32 $method=~s/.*://;
143             #warn sprintf("Autoloading Method: %s\n", $method);
144 6         20 foreach my $class ($self->packages) {
145 8 100       85 if ($class->can($method)) {
146             #warn(sprintf(qq{Package "%s" is loaded and method "%s" is supported\n}, $class, $method));
147 6         23 $self->autoload($class, $method);
148 6         13 last; #for performance and in case another package defines method.
149             } else {
150             #warn sprintf("Loading Package: %s\n", $class);
151 2         17 $class->use;
152 2 50       31 if ($@) {
153             #warn(sprintf(qq{Warning: Failed to use package "%s". Is it installed?\n}, $class));
154             } else {
155 0 0       0 if ($class->can($method)) {
156 0         0 $self->autoload($class, $method);
157 0         0 last; #for performance and in case another package defines method.
158             }
159             }
160             }
161             }
162 0         0 die(sprintf(qq{Error: Could not autoload method "%s" from packages %s.\n},
163 6 50       54 $method, join(", ", map {qq{"$_"}} $self->packages)))
164             unless $self->can($method);
165 6         30 return $self->$method(@_);
166             }
167              
168             =head2 autoload
169              
170             my $subref=$object->autoload($class, $method);
171              
172             =cut
173              
174             sub autoload {
175 6     6 1 11 my $syntax=q{Error: autoload syntax $obj->autoload($class, $method)};
176 6 50       27 my $self=shift or die($syntax);
177 6 50       20 my $class=shift or die($syntax);
178 6 50       19 my $method=shift or die($syntax);
179 6         17 my $sub=join("::", $class, $method);
180             #warn sprintf(qq{Importing method "%s" from class "%s"\n}, $method, $class);
181 6         19 $self->autoloaded->{$method}=$class;
182 6     6   4071 no strict qw{refs};
  6         11  
  6         433  
183 6         9 return *$method=\&{$sub};
  6         34  
184             }
185              
186             =head1 BUGS
187              
188             DavisNetworks.com provides support services for all Perl applications including this package.
189              
190             =head1 SUPPORT
191              
192             =head1 AUTHOR
193              
194             Michael R. Davis
195             CPAN ID: MRDVT
196             STOP, LLC
197             domain=>michaelrdavis,tld=>com,account=>perl
198             http://www.stopllc.com/
199              
200             =head1 COPYRIGHT
201              
202             This program is free software licensed under the...
203              
204             The BSD License
205              
206             The full text of the license can be found in the LICENSE file included with this module.
207              
208             =head1 SEE ALSO
209              
210             L AUTOMETHOD method,
211              
212             =cut
213              
214             1;