initial quite broken implementation of backend switching
[gitmo/Package-Stash.git] / lib / Package / Stash.pm
CommitLineData
e4afde02 1package Package::Stash;
2use strict;
3use warnings;
4# ABSTRACT: routines for manipulating stashes
5
6our $IMPLEMENTATION;
7
8BEGIN {
9 #warn "loading Package::Stash";
10 $IMPLEMENTATION = $ENV{PACKAGE_STASH_IMPLEMENTATION}
11 if exists $ENV{PACKAGE_STASH_IMPLEMENTATION};
12 #warn "found $IMPLEMENTATION" if $IMPLEMENTATION;
13
14 if (!$IMPLEMENTATION) {
15 #warn "detecting...";
16 for my $impl ('XS', 'PP') {
17 if (eval "require Package::Stash::$impl; 1;") {
18 #warn "found $impl";
19 $IMPLEMENTATION = $impl;
20 last;
21 }
22 }
23 }
24
25 if (!$IMPLEMENTATION) {
26 require Carp;
27 Carp::croak("Could not find a suitable Package::Stash implementation");
28 }
29
30 my $impl = "Package::Stash::$IMPLEMENTATION";
31 my $from = $impl->new($impl);
32 my $to = $impl->new(__PACKAGE__);
33 my $methods = $from->get_all_symbols('CODE');
34 for my $meth (keys %$methods) {
35 #warn "installing $meth";
36 $to->add_symbol("&$meth" => $methods->{$meth});
37 }
38}
39
40use Package::DeprecationManager -deprecations => {
41 'Package::Stash::add_package_symbol' => 0.14,
42 'Package::Stash::remove_package_glob' => 0.14,
43 'Package::Stash::has_package_symbol' => 0.14,
44 'Package::Stash::get_package_symbol' => 0.14,
45 'Package::Stash::get_or_add_package_symbol' => 0.14,
46 'Package::Stash::remove_package_symbol' => 0.14,
47 'Package::Stash::list_all_package_symbols' => 0.14,
48};
49
50sub add_package_symbol {
51 deprecated('add_package_symbol is deprecated, please use add_symbol');
52 shift->add_symbol(@_);
53}
54
55sub remove_package_glob {
56 deprecated('remove_package_glob is deprecated, please use remove_glob');
57 shift->remove_glob(@_);
58}
59
60sub has_package_symbol {
61 deprecated('has_package_symbol is deprecated, please use has_symbol');
62 shift->has_symbol(@_);
63}
64
65sub get_package_symbol {
66 deprecated('get_package_symbol is deprecated, please use get_symbol');
67 shift->get_symbol(@_);
68}
69
70sub get_or_add_package_symbol {
71 deprecated('get_or_add_package_symbol is deprecated, please use get_or_add_symbol');
72 shift->get_or_add_symbol(@_);
73}
74
75sub remove_package_symbol {
76 deprecated('remove_package_symbol is deprecated, please use remove_symbol');
77 shift->remove_symbol(@_);
78}
79
80sub list_all_package_symbols {
81 deprecated('list_all_package_symbols is deprecated, please use list_all_symbols');
82 shift->list_all_symbols(@_);
83}
84
85=head1 SYNOPSIS
86
87 my $stash = Package::Stash->new('Foo');
88 $stash->add_symbol('%foo', {bar => 1});
89 # $Foo::foo{bar} == 1
90 $stash->has_symbol('$foo') # false
91 my $namespace = $stash->namespace;
92 *{ $namespace->{foo} }{HASH} # {bar => 1}
93
94=head1 DESCRIPTION
95
96Manipulating stashes (Perl's symbol tables) is occasionally necessary, but
97incredibly messy, and easy to get wrong. This module hides all of that behind a
98simple API.
99
100NOTE: Most methods in this class require a variable specification that includes
101a sigil. If this sigil is absent, it is assumed to represent the IO slot.
102
103Due to limitations in the typeglob API available to perl code, and to typeglob
104manipulation in perl being quite slow, this module provides two
105implementations - one in pure perl, and one using XS. The XS implementation is
106to be preferred for most usages; the pure perl one is provided for cases where
107XS modules are not a possibility. The current implementation in use can be set
108by setting C<$ENV{PACKAGE_STASH_IMPLEMENTATION}> or
109C<$Package::Stash::IMPLEMENTATION> before loading Package::Stash (with the
110environment variable taking precedence), otherwise, it will use the XS
111implementation if possible, falling back to the pure perl one.
112
113=method new $package_name
114
115Creates a new C<Package::Stash> object, for the package given as the only
116argument.
117
118=method name
119
120Returns the name of the package that this object represents.
121
122=method namespace
123
124Returns the raw stash itself.
125
126=method add_symbol $variable $value %opts
127
128Adds a new package symbol, for the symbol given as C<$variable>, and optionally
129gives it an initial value of C<$value>. C<$variable> should be the name of
130variable including the sigil, so
131
132 Package::Stash->new('Foo')->add_symbol('%foo')
133
134will create C<%Foo::foo>.
135
136Valid options (all optional) are C<filename>, C<first_line_num>, and
137C<last_line_num>.
138
139C<$opts{filename}>, C<$opts{first_line_num}>, and C<$opts{last_line_num}> can
140be used to indicate where the symbol should be regarded as having been defined.
141Currently these values are only used if the symbol is a subroutine ('C<&>'
142sigil) and only if C<$^P & 0x10> is true, in which case the special C<%DB::sub>
143hash is updated to record the values of C<filename>, C<first_line_num>, and
144C<last_line_num> for the subroutine. If these are not passed, their values are
145inferred (as much as possible) from C<caller> information.
146
147This is especially useful for debuggers and profilers, which use C<%DB::sub> to
148determine where the source code for a subroutine can be found. See
149L<http://perldoc.perl.org/perldebguts.html#Debugger-Internals> for more
150information about C<%DB::sub>.
151
152=method remove_glob $name
153
154Removes all package variables with the given name, regardless of sigil.
155
156=method has_symbol $variable
157
158Returns whether or not the given package variable (including sigil) exists.
159
160=method get_symbol $variable
161
162Returns the value of the given package variable (including sigil).
163
164=method get_or_add_symbol $variable
165
166Like C<get_symbol>, except that it will return an empty hashref or
167arrayref if the variable doesn't exist.
168
169=method remove_symbol $variable
170
171Removes the package variable described by C<$variable> (which includes the
172sigil); other variables with the same name but different sigils will be
173untouched.
174
175=method list_all_symbols $type_filter
176
177Returns a list of package variable names in the package, without sigils. If a
178C<type_filter> is passed, it is used to select package variables of a given
179type, where valid types are the slots of a typeglob ('SCALAR', 'CODE', 'HASH',
180etc). Note that if the package contained any C<BEGIN> blocks, perl will leave
181an empty typeglob in the C<BEGIN> slot, so this will show up if no filter is
182used (and similarly for C<INIT>, C<END>, etc).
183
184=method get_all_symbols $type_filter
185
186Returns a hashref, keyed by the variable names in the package. If
187C<$type_filter> is passed, the hash will contain every variable of that type in
188the package as values, otherwise, it will contain the typeglobs corresponding
189to the variable names (basically, a clone of the stash).
190
191=head1 BUGS / CAVEATS
192
193=over 4
194
195=item * GLOB and FORMAT variables are not (yet) accessible through this module.
196
197=item * Also, see the BUGS section for the specific backends (L<Package::Stash::XS> and L<Package::Stash::PP>)
198
199=back
200
201Please report any bugs through RT: email
202C<bug-package-stash at rt.cpan.org>, or browse to
203L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Package-Stash>.
204
205=head1 SEE ALSO
206
207=over 4
208
209=item * L<Class::MOP::Package>
210
211This module is a factoring out of code that used to live here
212
213=back
214
215=head1 SUPPORT
216
217You can find this documentation for this module with the perldoc command.
218
219 perldoc Package::Stash
220
221You can also look for information at:
222
223=over 4
224
225=item * AnnoCPAN: Annotated CPAN documentation
226
227L<http://annocpan.org/dist/Package-Stash>
228
229=item * CPAN Ratings
230
231L<http://cpanratings.perl.org/d/Package-Stash>
232
233=item * RT: CPAN's request tracker
234
235L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Package-Stash>
236
237=item * Search CPAN
238
239L<http://search.cpan.org/dist/Package-Stash>
240
241=back
242
243=head1 AUTHOR
244
245Jesse Luehrs <doy at tozt dot net>
246
247Based on code from L<Class::MOP::Package>, by Stevan Little and the Moose
248Cabal.
249
250=begin Pod::Coverage
251
252add_package_symbol
253remove_package_glob
254has_package_symbol
255get_package_symbol
256get_or_add_package_symbol
257remove_package_symbol
258list_all_package_symbols
259
260=end Pod::Coverage
261
262=cut
263
2641;