Remove all trailing whitespace
[gitmo/Moose.git] / lib / Class / MOP / Package.pm
CommitLineData
38bf2a25 1
2package Class::MOP::Package;
3
4use strict;
5use warnings;
6
0db1c8dc 7use Scalar::Util 'blessed', 'reftype', 'weaken';
38bf2a25 8use Carp 'confess';
0db1c8dc 9use Devel::GlobalDestruction 'in_global_destruction';
38bf2a25 10use Package::Stash;
11
38bf2a25 12use base 'Class::MOP::Object';
13
14# creation ...
15
16sub initialize {
17 my ( $class, @args ) = @_;
18
19 unshift @args, "package" if @args % 2;
20
21 my %options = @args;
0db1c8dc 22 my $package_name = delete $options{package};
38bf2a25 23
24
064a13a3 25 # we hand-construct the class until we can bootstrap it
38bf2a25 26 if ( my $meta = Class::MOP::get_metaclass_by_name($package_name) ) {
27 return $meta;
28 } else {
29 my $meta = ( ref $class || $class )->_new({
30 'package' => $package_name,
31 %options,
32 });
33 Class::MOP::store_metaclass_by_name($package_name, $meta);
34
0db1c8dc 35 Class::MOP::weaken_metaclass($package_name) if $options{weaken};
36
37
38bf2a25 38 return $meta;
39 }
40}
41
42sub reinitialize {
43 my ( $class, @args ) = @_;
44
45 unshift @args, "package" if @args % 2;
46
47 my %options = @args;
48 my $package_name = delete $options{package};
49
50 (defined $package_name && $package_name
51 && (!blessed $package_name || $package_name->isa('Class::MOP::Package')))
52 || confess "You must pass a package name or an existing Class::MOP::Package instance";
53
54 $package_name = $package_name->name
55 if blessed $package_name;
56
57 Class::MOP::remove_metaclass_by_name($package_name);
58
59 $class->initialize($package_name, %options); # call with first arg form for compat
60}
61
0db1c8dc 62sub create {
63 my $class = shift;
64 my @args = @_;
65
66 return $class->initialize(@args);
67}
68
69## ANON packages
70
71{
72 # NOTE:
73 # this should be sufficient, if you have a
74 # use case where it is not, write a test and
75 # I will change it.
76 my $ANON_SERIAL = 0;
77
78 my %ANON_PACKAGE_CACHE;
79
80 # NOTE:
81 # we need a sufficiently annoying prefix
82 # this should suffice for now, this is
83 # used in a couple of places below, so
84 # need to put it up here for now.
85 sub _anon_package_prefix { 'Class::MOP::Package::__ANON__::SERIAL::' }
86
87 sub is_anon {
88 my $self = shift;
89 no warnings 'uninitialized';
90 my $prefix = $self->_anon_package_prefix;
9520ee8e 91 $self->name =~ /^\Q$prefix/;
0db1c8dc 92 }
93
94 sub create_anon {
95 my ($class, %options) = @_;
96
97 my $cache_ok = delete $options{cache};
85db9063 98 $options{weaken} = !$cache_ok unless exists $options{weaken};
0db1c8dc 99
4f629382 100 my $cache_key;
101 if ($cache_ok) {
102 $cache_key = $class->_anon_cache_key(%options);
83dcb866 103 undef $cache_ok if !defined($cache_key);
104 }
0db1c8dc 105
83dcb866 106 if ($cache_ok) {
4f629382 107 if (defined $ANON_PACKAGE_CACHE{$cache_key}) {
108 return $ANON_PACKAGE_CACHE{$cache_key};
109 }
0db1c8dc 110 }
111
0db1c8dc 112 my $package_name = $class->_anon_package_prefix . ++$ANON_SERIAL;
113
114 my $meta = $class->create($package_name, %options);
115
116 if ($cache_ok) {
117 $ANON_PACKAGE_CACHE{$cache_key} = $meta;
118 weaken($ANON_PACKAGE_CACHE{$cache_key});
119 }
120
121 return $meta;
122 }
123
124 sub _anon_cache_key { confess "Packages are not cacheable" }
125
126 sub DESTROY {
127 my $self = shift;
128
129 return if in_global_destruction(); # it'll happen soon anyway and this just makes things more complicated
130
131 $self->_free_anon
132 if $self->is_anon;
133 }
134
135 sub _free_anon {
136 my $self = shift;
137 my $name = $self->name;
138
139 # Moose does a weird thing where it replaces the metaclass for
140 # class when fixing metaclass incompatibility. In that case,
141 # we don't want to clean out the namespace now. We can detect
142 # that because Moose will explicitly update the singleton
143 # cache in Class::MOP.
144 no warnings 'uninitialized';
145 my $current_meta = Class::MOP::get_metaclass_by_name($name);
146 return if $current_meta ne $self;
147
148 my ($first_fragments, $last_fragment) = ($name =~ /^(.*)::(.*)$/);
149
150 no strict 'refs';
151 @{$name . '::ISA'} = ();
152 %{$name . '::'} = ();
153 delete ${$first_fragments . '::'}{$last_fragment . '::'};
154
155 Class::MOP::remove_metaclass_by_name($name);
156 }
157
158}
159
38bf2a25 160sub _new {
161 my $class = shift;
162
163 return Class::MOP::Class->initialize($class)->new_object(@_)
164 if $class ne __PACKAGE__;
165
166 my $params = @_ == 1 ? $_[0] : {@_};
167
168 return bless {
9c1bf11e 169 # Need to quote package to avoid a problem with PPI mis-parsing this
170 # as a package statement.
171 'package' => $params->{package},
38bf2a25 172
173 # NOTE:
174 # because of issues with the Perl API
175 # to the typeglob in some versions, we
176 # need to just always grab a new
177 # reference to the hash in the accessor.
178 # Ideally we could just store a ref and
179 # it would Just Work, but oh well :\
180
181 namespace => \undef,
182
183 } => $class;
184}
185
186# Attributes
187
188# NOTE:
064a13a3 189# all these attribute readers will be bootstrapped
38bf2a25 190# away in the Class::MOP bootstrap section
191
192sub _package_stash {
193 $_[0]->{_package_stash} ||= Package::Stash->new($_[0]->name)
194}
195sub namespace {
196 $_[0]->_package_stash->namespace
197}
198
199# Class attributes
200
201# ... these functions have to touch the symbol table itself,.. yuk
202
203sub add_package_symbol {
204 my $self = shift;
205 $self->_package_stash->add_symbol(@_);
206}
207
208sub remove_package_glob {
209 my $self = shift;
210 $self->_package_stash->remove_glob(@_);
211}
212
213# ... these functions deal with stuff on the namespace level
214
215sub has_package_symbol {
216 my $self = shift;
217 $self->_package_stash->has_symbol(@_);
218}
219
220sub get_package_symbol {
221 my $self = shift;
222 $self->_package_stash->get_symbol(@_);
223}
224
225sub get_or_add_package_symbol {
226 my $self = shift;
227 $self->_package_stash->get_or_add_symbol(@_);
228}
229
230sub remove_package_symbol {
231 my $self = shift;
232 $self->_package_stash->remove_symbol(@_);
233}
234
235sub list_all_package_symbols {
236 my $self = shift;
237 $self->_package_stash->list_all_symbols(@_);
238}
239
240sub get_all_package_symbols {
241 my $self = shift;
242 $self->_package_stash->get_all_symbols(@_);
243}
244
2451;
246
247# ABSTRACT: Package Meta Object
248
249__END__
250
251=pod
252
253=head1 DESCRIPTION
254
255The Package Protocol provides an abstraction of a Perl 5 package. A
256package is basically namespace, and this module provides methods for
257looking at and changing that namespace's symbol table.
258
259=head1 METHODS
260
261=over 4
262
57272677 263=item B<< Class::MOP::Package->initialize($package_name, %options) >>
38bf2a25 264
265This method creates a new C<Class::MOP::Package> instance which
266represents specified package. If an existing metaclass object exists
57272677 267for the package, that will be returned instead. No options are valid at the
268package level.
38bf2a25 269
57272677 270=item B<< Class::MOP::Package->reinitialize($package, %options) >>
38bf2a25 271
272This method forcibly removes any existing metaclass for the package
273before calling C<initialize>. In contrast to C<initialize>, you may
274also pass an existing C<Class::MOP::Package> instance instead of just
275a package name as C<$package>.
276
277Do not call this unless you know what you are doing.
278
57272677 279=item B<< Class::MOP::Package->create($package, %options) >>
280
281Creates a new C<Class::MOP::Package> instance which represents the specified
282package, and also does some initialization of that package. Currently, this
283just does the same thing as C<initialize>, but is overridden in subclasses,
284such as C<Class::MOP::Class>.
285
286=item B<< Class::MOP::Package->create_anon(%options) >>
287
288Creates a new anonymous package. Valid keys for C<%options> are:
289
290=over 4
291
292=item C<weaken>
293
294If this is true (the default), the instance stored in C<Class::MOP>'s metaclass
295cache will be weakened, so that the anonymous package will be garbage collected
296when the returned instance goes out of scope.
297
298=back
299
300=item B<< $metapackage->is_anon >>
301
302Returns true if the package is an anonymous package.
303
38bf2a25 304=item B<< $metapackage->name >>
305
306This is returns the package's name, as passed to the constructor.
307
308=item B<< $metapackage->namespace >>
309
310This returns a hash reference to the package's symbol table. The keys
311are symbol names and the values are typeglob references.
312
313=item B<< $metapackage->add_package_symbol($variable_name, $initial_value) >>
314
315This method accepts a variable name and an optional initial value. The
316C<$variable_name> must contain a leading sigil.
317
318This method creates the variable in the package's symbol table, and
319sets it to the initial value if one was provided.
320
321=item B<< $metapackage->get_package_symbol($variable_name) >>
322
323Given a variable name, this method returns the variable as a reference
324or undef if it does not exist. The C<$variable_name> must contain a
325leading sigil.
326
327=item B<< $metapackage->get_or_add_package_symbol($variable_name) >>
328
329Given a variable name, this method returns the variable as a reference.
330If it does not exist, a default value will be generated if possible. The
331C<$variable_name> must contain a leading sigil.
332
333=item B<< $metapackage->has_package_symbol($variable_name) >>
334
335Returns true if there is a package variable defined for
336C<$variable_name>. The C<$variable_name> must contain a leading sigil.
337
338=item B<< $metapackage->remove_package_symbol($variable_name) >>
339
340This will remove the package variable specified C<$variable_name>. The
341C<$variable_name> must contain a leading sigil.
342
343=item B<< $metapackage->remove_package_glob($glob_name) >>
344
345Given the name of a glob, this will remove that glob from the
346package's symbol table. Glob names do not include a sigil. Removing
347the glob removes all variables and subroutines with the specified
348name.
349
350=item B<< $metapackage->list_all_package_symbols($type_filter) >>
351
352This will list all the glob names associated with the current
353package. These names do not have leading sigils.
354
355You can provide an optional type filter, which should be one of
356'SCALAR', 'ARRAY', 'HASH', or 'CODE'.
357
358=item B<< $metapackage->get_all_package_symbols($type_filter) >>
359
360This works much like C<list_all_package_symbols>, but it returns a
361hash reference. The keys are glob names and the values are references
362to the value for that name.
363
364=item B<< Class::MOP::Package->meta >>
365
366This will return a L<Class::MOP::Class> instance for this class.
367
368=back
369
370=cut