Import namespace-clean-0.02.tar.gz.
[p5sagit/namespace-clean.git] / lib / namespace / clean.pm
CommitLineData
40aef9d6 1package namespace::clean;
2
3=head1 NAME
4
5namespace::clean - Keep imports out of your namespace
6
7=cut
8
9use warnings;
10use strict;
11
9b680ffe 12use vars qw( $VERSION $STORAGE_VAR );
40aef9d6 13use Symbol qw( qualify_to_ref );
14use Filter::EOF;
15
16=head1 VERSION
17
9b680ffe 180.02
40aef9d6 19
20=cut
21
9b680ffe 22$VERSION = 0.02;
23$STORAGE_VAR = '__NAMESPACE_CLEAN_STORAGE';
40aef9d6 24
25=head1 SYNOPSIS
26
27 package Foo;
28 use warnings;
29 use strict;
30
31 use Carp qw(croak); # will be removed
32
33 sub bar { 23 } # will be removed
34
35 use namespace::clean;
36
37 sub baz { bar() } # still defined, 'bar' still bound
38
9b680ffe 39 no namespace::clean;
40
41 sub quux { baz() } # will be removed again
42
43 use namespace::clean;
44
40aef9d6 45 ### Will print:
46 # No
47 # No
48 # Yes
9b680ffe 49 # No
40aef9d6 50 print +(__PACKAGE__->can('croak') ? 'Yes' : 'No'), "\n";
51 print +(__PACKAGE__->can('bar') ? 'Yes' : 'No'), "\n";
52 print +(__PACKAGE__->can('baz') ? 'Yes' : 'No'), "\n";
9b680ffe 53 print +(__PACKAGE__->can('quux') ? 'Yes' : 'No'), "\n";
40aef9d6 54
55 1;
56
57=head1 DESCRIPTION
58
59When you define a function, or import one, into a Perl package, it will
60naturally also be available as a method. This does not per se cause
61problems, but it can complicate subclassing and, for example, plugin
62classes that are included by loading them as base classes.
63
64The C<namespace::clean> pragma will remove all previously declared or
65imported symbols at the end of the current package's compile cycle.
66This means that functions are already bound by their name, and calls to
67them still work. But they will not be available as methods on your class
68or instances.
69
70=head1 METHODS
71
72You shouldn't need to call any of these. Just C<use> the package at the
73appropriate place.
74
75=head2 import
76
77Makes a snapshot of the current defined functions and registers a
78L<Filter::EOF> cleanup routine to remove those symbols from the package
79at the end of the compile-time.
80
81=cut
82
83sub import {
84 my ($pragma) = @_;
85
86 my $cleanee = caller;
87 my $functions = $pragma->get_functions($cleanee);
9b680ffe 88 my $store = $pragma->get_class_store($cleanee);
40aef9d6 89
9b680ffe 90 for my $f (keys %$functions) {
91 next unless $functions->{ $f }
92 and *{ $functions->{ $f } }{CODE};
93 $store->{remove}{ $f } = 1;
94 }
95
96 unless ($store->{handler_is_installed}) {
97 Filter::EOF->on_eof_call(sub {
98 for my $f (keys %{ $store->{remove} }) {
99 next if $store->{exclude}{ $f };
100 no strict 'refs';
40aef9d6 101 delete ${ "${cleanee}::" }{ $f };
102 }
9b680ffe 103 });
104 $store->{handler_is_installed} = 1;
105 }
106
107 return 1;
108}
109
110=head2 unimport
111
112This method will be called when you do a
113
114 no namespace::clean;
115
116It will start a new section of code that defines functions to clean up.
117
118=cut
119
120sub unimport {
121 my ($pragma) = @_;
122
123 my $cleanee = caller;
124 my $functions = $pragma->get_functions($cleanee);
125 my $store = $pragma->get_class_store($cleanee);
126
127 for my $f (keys %$functions) {
128 next if $store->{remove}{ $f }
129 or $store->{exclude}{ $f };
130 $store->{exclude}{ $f } = 1;
131 }
132
133 return 1;
134}
135
136=head2 get_class_store
137
138This returns a reference to a hash in your package containing information
139about function names included and excluded from removal.
140
141=cut
142
143sub get_class_store {
144 my ($pragma, $class) = @_;
145 no strict 'refs';
146 return \%{ "${class}::${STORAGE_VAR}" };
40aef9d6 147}
148
149=head2 get_functions
150
151Takes a class as argument and returns all currently defined functions
152in it as a hash reference with the function name as key and a typeglob
153reference to the symbol as value.
154
155=cut
156
157sub get_functions {
158 my ($pragma, $class) = @_;
159
160 return {
161 map { @$_ }
162 grep { *{ $_->[1] }{CODE} }
163 map { [$_, qualify_to_ref( $_, $class )] }
164 grep { $_ !~ /::$/ }
165 do { no strict 'refs'; keys %{ "${class}::" } }
166 };
167}
168
169=head1 SEE ALSO
170
171L<Filter::EOF>
172
173=head1 AUTHOR AND COPYRIGHT
174
175Robert 'phaylon' Sedlacek C<E<lt>rs@474.atE<gt>>, with many thanks to
176Matt S Trout for the inspiration on the whole idea.
177
178=head1 LICENSE
179
180This program is free software; you can redistribute it and/or modify
181it under the same terms as perl itself.
182
183=cut
184
1851;