This is patch.2b1f to perl5.002beta1.
[p5sagit/p5-mst-13.2.git] / lib / Devel / SelfStubber.pm
CommitLineData
f8881bd9 1package Devel::SelfStubber;
2require SelfLoader;
3@ISA = qw(SelfLoader);
4$JUST_STUBS = 1;
5$VERSION = 1.01; sub Version {$VERSION}
6
7# Use as
8# perl -e 'use Devel::SelfStubber;Devel::SelfStubber->stub(MODULE_NAME,LIB)'
9# (LIB defaults to '.') e.g.
10# perl -e 'use Devel::SelfStubber;Devel::SelfStubber->stub('Math::BigInt')'
11# would print out stubs needed if you added a __DATA__ before the subs.
12# Setting $Devel::SelfStubber::JUST_STUBS to 0 will print out the whole
13# module with the stubs entered just before the __DATA__
14
15sub _add_to_cache {
16 my($self,$fullname,$pack,$lines, $prototype) = @_;
17 push(@DATA,@{$lines});
18 if($fullname){push(@STUBS,"sub $fullname $prototype;\n")}; # stubs
19 '1;';
20}
21
22sub _package_defined {
23 my($self,$line) = @_;
24 push(@DATA,$line);
25}
26
27sub stub {
28 my($self,$module,$lib) = @_;
29 my($line,$end,$fh,$mod_file,$found_selfloader);
30 $lib ||= '.';
31 ($mod_file = $module) =~ s,::,/,g;
32
33 $mod_file = "$lib/$mod_file.pm";
34 $fh = "${module}::DATA";
35
36 open($fh,$mod_file) || die "Unable to open $mod_file";
37 while($line = <$fh> and $line !~ m/^__DATA__/) {
38 push(@BEFORE_DATA,$line);
39 $line =~ /use\s+SelfLoader/ && $found_selfloader++;
40 }
41 $line =~ m/^__DATA__/ || die "$mod_file doesn't contain a __DATA__ token";
42 $found_selfloader ||
43 print 'die "\'use SelfLoader;\' statement NOT FOUND!!\n"',"\n";
44 $self->_load_stubs($module);
45 if ( fileno($fh) ) {
46 $end = 1;
47 while($line = <$fh>) {
48 push(@AFTER_DATA,$line);
49 }
50 }
51 unless ($JUST_STUBS) {
52 print @BEFORE_DATA;
53 }
54 print @STUBS;
55 unless ($JUST_STUBS) {
56 print "1;\n__DATA__\n",@DATA;
57 if($end) { print "__END__\n",@AFTER_DATA; }
58 }
59}
60
611;
62__END__
63=head1 NAME
64
65Devel::SelfStubber - generate stubs for a SelfLoading module
66
67=head1 SYNOPSIS
68
69To generate just the stubs:
70
71 use Devel::SelfStubber;
72 Devel::SelfStubber->stub('MODULENAME','MY_LIB_DIR');
73
74or to generate the whole module with stubs inserted correctly
75
76 use Devel::SelfStubber;
77 $Devel::SelfStubber::JUST_STUBS=0;
78 Devel::SelfStubber->stub('MODULENAME','MY_LIB_DIR');
79
80MODULENAME is the Perl module name, e.g. Devel::SelfStubber,
81NOT 'Devel/SelfStubber' or 'Devel/SelfStubber.pm'.
82
83MY_LIB_DIR defaults to '.' if not present.
84
85=head1 DESCRIPTION
86
87Devel::SelfStubber prints the stubs you need to put in the module
88before the __DATA__ token (or you can get it to print the entire
89module with stubs correctly placed). The stubs ensure that if
90a method is called, it will get loaded. They are needed specifically
91for inherited autoloaded methods.
92
93This is best explained using the following example:
94
95Assume four classes, A,B,C & D.
96
97A is the root class, B is a subclass of A, C is a subclass of B,
98and D is another subclass of A.
99
100 A
101 / \
102 B D
103 /
104 C
105
106If D calls an autoloaded method 'foo' which is defined in class A,
107then the method is loaded into class A, then executed. If C then
108calls method 'foo', and that method was reimplemented in class
109B, but set to be autoloaded, then the lookup mechanism never gets to
110the AUTOLOAD mechanism in B because it first finds the method
111already loaded in A, and so erroneously uses that. If the method
112foo had been stubbed in B, then the lookup mechanism would have
113found the stub, and correctly loaded and used the sub from B.
114
115So, for classes and subclasses to have inheritance correctly
116work with autoloading, you need to ensure stubs are loaded.
117
118The SelfLoader can load stubs automatically at module initialization
119with the statement 'SelfLoader->load_stubs()';, but you may wish to
120avoid having the stub loading overhead associated with your
121initialization (though note that the SelfLoader::load_stubs method
122will be called sooner or later - at latest when the first sub
123is being autoloaded). In this case, you can put the sub stubs
124before the __DATA__ token. This can be done manually, but this
125module allows automatic generation of the stubs.
126
127By default it just prints the stubs, but you can set the
128global $Devel::SelfStubber::JUST_STUBS to 0 and it will
129print out the entire module with the stubs positioned correctly.
130
131At the very least, this is useful to see what the SelfLoader
132thinks are stubs - in order to ensure future versions of the
133SelfStubber remain in step with the SelfLoader, the
134SelfStubber actually uses the SelfLoader to determine which
135stubs are needed.
136
137=cut