079d28a0d61df29fa499e949ee4527298308689c
[gitmo/Moose.git] / lib / Class / MOP / Package.pm
1
2 package Class::MOP::Package;
3
4 use strict;
5 use warnings;
6
7 use Scalar::Util 'blessed', 'reftype', 'weaken';
8 use Carp         'confess';
9 use Devel::GlobalDestruction 'in_global_destruction';
10 use Package::Stash;
11
12 use base 'Class::MOP::Object';
13
14 # creation ...
15
16 sub initialize {
17     my ( $class, @args ) = @_;
18
19     unshift @args, "package" if @args % 2;
20
21     my %options = @args;
22     my $package_name = delete $options{package};
23
24
25     # we hand-construct the class until we can bootstrap it
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
35         Class::MOP::weaken_metaclass($package_name) if $options{weaken};
36
37
38         return $meta;
39     }
40 }
41
42 sub 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
62 sub 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;
91         $self->name =~ /^\Q$prefix/;
92     }
93
94     sub create_anon {
95         my ($class, %options) = @_;
96
97         my $cache_ok = delete $options{cache};
98         $options{weaken} = !$cache_ok unless exists $options{weaken};
99
100         my $cache_key;
101         if ($cache_ok) {
102             $cache_key = $class->_anon_cache_key(%options);
103             undef $cache_ok if !defined($cache_key);
104         }
105
106         if ($cache_ok) {
107             if (defined $ANON_PACKAGE_CACHE{$cache_key}) {
108                 return $ANON_PACKAGE_CACHE{$cache_key};
109             }
110         }
111
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 using store_metaclass_by_name, which
144         # means that the new metaclass will already exist in the cache
145         # by this point.
146         # The other options here are that $current_meta can be undef if
147         # remove_metaclass_by_name is called explicitly (since the hash
148         # entry is removed first, and then this destructor is called),
149         # or that $current_meta can be the same as $self, which happens
150         # when the metaclass goes out of scope (since the weak reference
151         # in the metaclass cache won't be freed until after this
152         # destructor runs).
153         my $current_meta = Class::MOP::get_metaclass_by_name($name);
154         return if defined($current_meta) && $current_meta ne $self;
155
156         my ($first_fragments, $last_fragment) = ($name =~ /^(.*)::(.*)$/);
157
158         no strict 'refs';
159         @{$name . '::ISA'} = ();
160         %{$name . '::'}    = ();
161         delete ${$first_fragments . '::'}{$last_fragment . '::'};
162
163         Class::MOP::remove_metaclass_by_name($name);
164     }
165
166 }
167
168 sub _new {
169     my $class = shift;
170
171     return Class::MOP::Class->initialize($class)->new_object(@_)
172         if $class ne __PACKAGE__;
173
174     my $params = @_ == 1 ? $_[0] : {@_};
175
176     return bless {
177         # Need to quote package to avoid a problem with PPI mis-parsing this
178         # as a package statement.
179         'package' => $params->{package},
180
181         # NOTE:
182         # because of issues with the Perl API
183         # to the typeglob in some versions, we
184         # need to just always grab a new
185         # reference to the hash in the accessor.
186         # Ideally we could just store a ref and
187         # it would Just Work, but oh well :\
188
189         namespace => \undef,
190
191     } => $class;
192 }
193
194 # Attributes
195
196 # NOTE:
197 # all these attribute readers will be bootstrapped
198 # away in the Class::MOP bootstrap section
199
200 sub _package_stash {
201     $_[0]->{_package_stash} ||= Package::Stash->new($_[0]->name)
202 }
203 sub namespace {
204     $_[0]->_package_stash->namespace
205 }
206
207 # Class attributes
208
209 # ... these functions have to touch the symbol table itself,.. yuk
210
211 sub add_package_symbol {
212     my $self = shift;
213     $self->_package_stash->add_symbol(@_);
214 }
215
216 sub remove_package_glob {
217     my $self = shift;
218     $self->_package_stash->remove_glob(@_);
219 }
220
221 # ... these functions deal with stuff on the namespace level
222
223 sub has_package_symbol {
224     my $self = shift;
225     $self->_package_stash->has_symbol(@_);
226 }
227
228 sub get_package_symbol {
229     my $self = shift;
230     $self->_package_stash->get_symbol(@_);
231 }
232
233 sub get_or_add_package_symbol {
234     my $self = shift;
235     $self->_package_stash->get_or_add_symbol(@_);
236 }
237
238 sub remove_package_symbol {
239     my $self = shift;
240     $self->_package_stash->remove_symbol(@_);
241 }
242
243 sub list_all_package_symbols {
244     my $self = shift;
245     $self->_package_stash->list_all_symbols(@_);
246 }
247
248 sub get_all_package_symbols {
249     my $self = shift;
250     $self->_package_stash->get_all_symbols(@_);
251 }
252
253 1;
254
255 # ABSTRACT: Package Meta Object
256
257 __END__
258
259 =pod
260
261 =head1 DESCRIPTION
262
263 The Package Protocol provides an abstraction of a Perl 5 package. A
264 package is basically namespace, and this module provides methods for
265 looking at and changing that namespace's symbol table.
266
267 =head1 METHODS
268
269 =over 4
270
271 =item B<< Class::MOP::Package->initialize($package_name, %options) >>
272
273 This method creates a new C<Class::MOP::Package> instance which
274 represents specified package. If an existing metaclass object exists
275 for the package, that will be returned instead. No options are valid at the
276 package level.
277
278 =item B<< Class::MOP::Package->reinitialize($package, %options) >>
279
280 This method forcibly removes any existing metaclass for the package
281 before calling C<initialize>. In contrast to C<initialize>, you may
282 also pass an existing C<Class::MOP::Package> instance instead of just
283 a package name as C<$package>.
284
285 Do not call this unless you know what you are doing.
286
287 =item B<< Class::MOP::Package->create($package, %options) >>
288
289 Creates a new C<Class::MOP::Package> instance which represents the specified
290 package, and also does some initialization of that package. Currently, this
291 just does the same thing as C<initialize>, but is overridden in subclasses,
292 such as C<Class::MOP::Class>.
293
294 =item B<< Class::MOP::Package->create_anon(%options) >>
295
296 Creates a new anonymous package. Valid keys for C<%options> are:
297
298 =over 4
299
300 =item C<weaken>
301
302 If this is true (the default), the instance stored in C<Class::MOP>'s metaclass
303 cache will be weakened, so that the anonymous package will be garbage collected
304 when the returned instance goes out of scope.
305
306 =back
307
308 =item B<< $metapackage->is_anon >>
309
310 Returns true if the package is an anonymous package.
311
312 =item B<< $metapackage->name >>
313
314 This is returns the package's name, as passed to the constructor.
315
316 =item B<< $metapackage->namespace >>
317
318 This returns a hash reference to the package's symbol table. The keys
319 are symbol names and the values are typeglob references.
320
321 =item B<< $metapackage->add_package_symbol($variable_name, $initial_value) >>
322
323 This method accepts a variable name and an optional initial value. The
324 C<$variable_name> must contain a leading sigil.
325
326 This method creates the variable in the package's symbol table, and
327 sets it to the initial value if one was provided.
328
329 =item B<< $metapackage->get_package_symbol($variable_name) >>
330
331 Given a variable name, this method returns the variable as a reference
332 or undef if it does not exist. The C<$variable_name> must contain a
333 leading sigil.
334
335 =item B<< $metapackage->get_or_add_package_symbol($variable_name) >>
336
337 Given a variable name, this method returns the variable as a reference.
338 If it does not exist, a default value will be generated if possible. The
339 C<$variable_name> must contain a leading sigil.
340
341 =item B<< $metapackage->has_package_symbol($variable_name) >>
342
343 Returns true if there is a package variable defined for
344 C<$variable_name>. The C<$variable_name> must contain a leading sigil.
345
346 =item B<< $metapackage->remove_package_symbol($variable_name) >>
347
348 This will remove the package variable specified C<$variable_name>. The
349 C<$variable_name> must contain a leading sigil.
350
351 =item B<< $metapackage->remove_package_glob($glob_name) >>
352
353 Given the name of a glob, this will remove that glob from the
354 package's symbol table. Glob names do not include a sigil. Removing
355 the glob removes all variables and subroutines with the specified
356 name.
357
358 =item B<< $metapackage->list_all_package_symbols($type_filter) >>
359
360 This will list all the glob names associated with the current
361 package. These names do not have leading sigils.
362
363 You can provide an optional type filter, which should be one of
364 'SCALAR', 'ARRAY', 'HASH', or 'CODE'.
365
366 =item B<< $metapackage->get_all_package_symbols($type_filter) >>
367
368 This works much like C<list_all_package_symbols>, but it returns a
369 hash reference. The keys are glob names and the values are references
370 to the value for that name.
371
372 =item B<< Class::MOP::Package->meta >>
373
374 This will return a L<Class::MOP::Class> instance for this class.
375
376 =back
377
378 =cut