a number of changes;
[gitmo/Class-MOP.git] / lib / Class / MOP / Class.pm
CommitLineData
8b978dd5 1
2package Class::MOP::Class;
3
4use strict;
5use warnings;
6
7use Carp 'confess';
0882828e 8use Scalar::Util 'blessed', 'reftype';
8b978dd5 9use Sub::Name 'subname';
10use B 'svref_2object';
11
99e5b7e8 12our $VERSION = '0.03';
8b978dd5 13
2eb717d5 14# Self-introspection
15
99e5b7e8 16sub meta { Class::MOP::Class->initialize($_[0]) }
2eb717d5 17
8b978dd5 18# Creation
19
bfe4d0fc 20{
21 # Metaclasses are singletons, so we cache them here.
22 # there is no need to worry about destruction though
23 # because they should die only when the program dies.
24 # After all, do package definitions even get reaped?
25 my %METAS;
26 sub initialize {
351bd7d4 27 my $class = shift;
28 my $package_name = shift;
bfe4d0fc 29 (defined $package_name && $package_name)
c9e77dbb 30 || confess "You must pass a package name";
31 # make sure the package name is not blessed
32 $package_name = blessed($package_name) || $package_name;
727919c5 33 return $METAS{$package_name} if exists $METAS{$package_name};
351bd7d4 34 $METAS{$package_name} = $class->construct_class_instance($package_name, @_);
727919c5 35 }
36
37 # NOTE: (meta-circularity)
38 # this is a special form of &construct_instance
39 # (see below), which is used to construct class
1a7ebbb3 40 # meta-object instances for any Class::MOP::*
41 # class. All other classes will use the more
42 # normal &construct_instance.
727919c5 43 sub construct_class_instance {
351bd7d4 44 my $class = shift;
45 my $package_name = shift;
727919c5 46 (defined $package_name && $package_name)
1a7ebbb3 47 || confess "You must pass a package name";
48 $class = blessed($class) || $class;
49 if ($class =~ /^Class::MOP::/) {
50 bless {
351bd7d4 51 '$:package' => $package_name,
52 '%:attributes' => {},
53 '$:attribute_metaclass' => 'Class::MOP::Attribute',
54 '$:method_metaclass' => 'Class::MOP::Method',
1a7ebbb3 55 } => $class;
56 }
57 else {
351bd7d4 58 bless $class->meta->construct_instance(':package' => $package_name, @_) => $class
1a7ebbb3 59 }
bfe4d0fc 60 }
8b978dd5 61}
62
63sub create {
64 my ($class, $package_name, $package_version, %options) = @_;
bfe4d0fc 65 (defined $package_name && $package_name)
8b978dd5 66 || confess "You must pass a package name";
67 my $code = "package $package_name;";
68 $code .= "\$$package_name\:\:VERSION = '$package_version';"
69 if defined $package_version;
70 eval $code;
71 confess "creation of $package_name failed : $@" if $@;
bfe4d0fc 72 my $meta = $class->initialize($package_name);
8b978dd5 73 $meta->superclasses(@{$options{superclasses}})
74 if exists $options{superclasses};
2eb717d5 75 # NOTE:
76 # process attributes first, so that they can
77 # install accessors, but locally defined methods
78 # can then overwrite them. It is maybe a little odd, but
79 # I think this should be the order of things.
80 if (exists $options{attributes}) {
cbd9f942 81 foreach my $attr (@{$options{attributes}}) {
82 $meta->add_attribute($attr);
2eb717d5 83 }
84 }
bfe4d0fc 85 if (exists $options{methods}) {
86 foreach my $method_name (keys %{$options{methods}}) {
87 $meta->add_method($method_name, $options{methods}->{$method_name});
88 }
2eb717d5 89 }
8b978dd5 90 return $meta;
91}
92
c9e77dbb 93# Instance Construction & Cloning
94
e16da3e6 95
96sub construct_instance {
cbd9f942 97 my ($class, %params) = @_;
98 my $instance = {};
c9e77dbb 99 foreach my $attr ($class->compute_all_applicable_attributes()) {
cbd9f942 100 my $init_arg = $attr->has_init_arg() ? $attr->init_arg() : $attr->name;
101 # try to fetch the init arg from the %params ...
102 my $val;
103 $val = $params{$init_arg} if exists $params{$init_arg};
104 # if nothing was in the %params, we can use the
105 # attribute's default value (if it has one)
c9e77dbb 106 $val ||= $attr->default($instance) if $attr->has_default();
cbd9f942 107 $instance->{$attr->name} = $val;
108 }
109 return $instance;
e16da3e6 110}
111
c9e77dbb 112sub clone_instance {
113 my ($class, $self, %params) = @_;
114 (blessed($self))
115 || confess "You can only clone instances, \$self is not a blessed instance";
116 # NOTE:
117 # this should actually do a deep clone
118 # instead of this cheap hack. I will
119 # add that in later.
120 # (use the Class::Cloneable::Util code)
121 my $clone = { %{$self} };
122 foreach my $attr ($class->compute_all_applicable_attributes()) {
123 my $init_arg = $attr->has_init_arg() ? $attr->init_arg() : $attr->name;
124 # try to fetch the init arg from the %params ...
125 $clone->{$attr->name} = $params{$init_arg}
126 if exists $params{$init_arg};
127 }
128 return $clone;
129}
130
8b978dd5 131# Informational
132
351bd7d4 133sub name { $_[0]->{'$:package'} }
8b978dd5 134
135sub version {
136 my $self = shift;
137 no strict 'refs';
138 ${$self->name . '::VERSION'};
139}
140
141# Inheritance
142
143sub superclasses {
144 my $self = shift;
145 no strict 'refs';
146 if (@_) {
147 my @supers = @_;
148 @{$self->name . '::ISA'} = @supers;
149 }
150 @{$self->name . '::ISA'};
151}
152
153sub class_precedence_list {
154 my $self = shift;
bfe4d0fc 155 # NOTE:
156 # We need to check for ciruclar inheirtance here.
157 # This will do nothing if all is well, and blow
158 # up otherwise. Yes, it's an ugly hack, better
159 # suggestions are welcome.
160 { $self->name->isa('This is a test for circular inheritance') }
161 # ... and no back to our regularly scheduled program
8b978dd5 162 (
163 $self->name,
164 map {
bfe4d0fc 165 $self->initialize($_)->class_precedence_list()
8b978dd5 166 } $self->superclasses()
167 );
168}
169
0882828e 170## Methods
171
2e41896e 172# un-used right now ...
351bd7d4 173sub method_metaclass { $_[0]->{'$:method_metaclass'} }
2e41896e 174
0882828e 175sub add_method {
176 my ($self, $method_name, $method) = @_;
177 (defined $method_name && $method_name)
178 || confess "You must define a method name";
a5eca695 179 # use reftype here to allow for blessed subs ...
0882828e 180 (reftype($method) && reftype($method) eq 'CODE')
181 || confess "Your code block must be a CODE reference";
182 my $full_method_name = ($self->name . '::' . $method_name);
183
184 no strict 'refs';
c9b8b7f9 185 no warnings 'redefine';
0882828e 186 *{$full_method_name} = subname $full_method_name => $method;
187}
188
bfe4d0fc 189{
190
191 ## private utility functions for has_method
2eb717d5 192 my $_find_subroutine_package_name = sub { eval { svref_2object($_[0])->GV->STASH->NAME } || '' };
193 my $_find_subroutine_name = sub { eval { svref_2object($_[0])->GV->NAME } || '' };
bfe4d0fc 194
195 sub has_method {
c9b8b7f9 196 my ($self, $method_name) = @_;
bfe4d0fc 197 (defined $method_name && $method_name)
198 || confess "You must define a method name";
0882828e 199
bfe4d0fc 200 my $sub_name = ($self->name . '::' . $method_name);
0882828e 201
bfe4d0fc 202 no strict 'refs';
203 return 0 if !defined(&{$sub_name});
204 return 0 if $_find_subroutine_package_name->(\&{$sub_name}) ne $self->name &&
205 $_find_subroutine_name->(\&{$sub_name}) ne '__ANON__';
206 return 1;
207 }
208
0882828e 209}
210
211sub get_method {
c9b8b7f9 212 my ($self, $method_name) = @_;
0882828e 213 (defined $method_name && $method_name)
214 || confess "You must define a method name";
215
216 no strict 'refs';
217 return \&{$self->name . '::' . $method_name}
bfe4d0fc 218 if $self->has_method($method_name);
c9b8b7f9 219 return; # <- make sure to return undef
220}
221
222sub remove_method {
223 my ($self, $method_name) = @_;
224 (defined $method_name && $method_name)
225 || confess "You must define a method name";
226
227 my $removed_method = $self->get_method($method_name);
228
229 no strict 'refs';
230 delete ${$self->name . '::'}{$method_name}
231 if defined $removed_method;
232
233 return $removed_method;
234}
235
236sub get_method_list {
237 my $self = shift;
238 no strict 'refs';
a5eca695 239 grep { $self->has_method($_) } %{$self->name . '::'};
240}
241
242sub compute_all_applicable_methods {
243 my $self = shift;
244 my @methods;
245 # keep a record of what we have seen
246 # here, this will handle all the
247 # inheritence issues because we are
248 # using the &class_precedence_list
249 my (%seen_class, %seen_method);
250 foreach my $class ($self->class_precedence_list()) {
251 next if $seen_class{$class};
252 $seen_class{$class}++;
253 # fetch the meta-class ...
254 my $meta = $self->initialize($class);
255 foreach my $method_name ($meta->get_method_list()) {
256 next if exists $seen_method{$method_name};
257 $seen_method{$method_name}++;
258 push @methods => {
259 name => $method_name,
260 class => $class,
261 code => $meta->get_method($method_name)
262 };
263 }
264 }
265 return @methods;
266}
267
a5eca695 268sub find_all_methods_by_name {
269 my ($self, $method_name) = @_;
270 (defined $method_name && $method_name)
271 || confess "You must define a method name to find";
272 my @methods;
273 # keep a record of what we have seen
274 # here, this will handle all the
275 # inheritence issues because we are
276 # using the &class_precedence_list
277 my %seen_class;
278 foreach my $class ($self->class_precedence_list()) {
279 next if $seen_class{$class};
280 $seen_class{$class}++;
281 # fetch the meta-class ...
282 my $meta = $self->initialize($class);
283 push @methods => {
284 name => $method_name,
285 class => $class,
286 code => $meta->get_method($method_name)
287 } if $meta->has_method($method_name);
288 }
289 return @methods;
290
8b978dd5 291}
292
552e3d24 293## Attributes
294
351bd7d4 295sub attribute_metaclass { $_[0]->{'$:attribute_metaclass'} }
2e41896e 296
e16da3e6 297sub add_attribute {
2e41896e 298 my $self = shift;
299 # either we have an attribute object already
300 # or we need to create one from the args provided
301 my $attribute = blessed($_[0]) ? $_[0] : $self->attribute_metaclass->new(@_);
302 # make sure it is derived from the correct type though
303 ($attribute->isa('Class::MOP::Attribute'))
304 || confess "Your attribute must be an instance of Class::MOP::Attribute (or a subclass)";
9ec169fe 305 $attribute->attach_to_class($self);
306 $attribute->install_accessors();
2eb717d5 307 $self->{'%:attrs'}->{$attribute->name} = $attribute;
e16da3e6 308}
309
310sub has_attribute {
311 my ($self, $attribute_name) = @_;
312 (defined $attribute_name && $attribute_name)
313 || confess "You must define an attribute name";
314 exists $self->{'%:attrs'}->{$attribute_name} ? 1 : 0;
315}
316
317sub get_attribute {
318 my ($self, $attribute_name) = @_;
319 (defined $attribute_name && $attribute_name)
320 || confess "You must define an attribute name";
321 return $self->{'%:attrs'}->{$attribute_name}
322 if $self->has_attribute($attribute_name);
323}
324
325sub remove_attribute {
326 my ($self, $attribute_name) = @_;
327 (defined $attribute_name && $attribute_name)
328 || confess "You must define an attribute name";
329 my $removed_attribute = $self->{'%:attrs'}->{$attribute_name};
330 delete $self->{'%:attrs'}->{$attribute_name}
9ec169fe 331 if defined $removed_attribute;
332 $removed_attribute->remove_accessors();
333 $removed_attribute->detach_from_class();
e16da3e6 334 return $removed_attribute;
335}
336
337sub get_attribute_list {
338 my $self = shift;
339 keys %{$self->{'%:attrs'}};
340}
341
342sub compute_all_applicable_attributes {
343 my $self = shift;
344 my @attrs;
345 # keep a record of what we have seen
346 # here, this will handle all the
347 # inheritence issues because we are
348 # using the &class_precedence_list
349 my (%seen_class, %seen_attr);
350 foreach my $class ($self->class_precedence_list()) {
351 next if $seen_class{$class};
352 $seen_class{$class}++;
353 # fetch the meta-class ...
354 my $meta = $self->initialize($class);
355 foreach my $attr_name ($meta->get_attribute_list()) {
356 next if exists $seen_attr{$attr_name};
357 $seen_attr{$attr_name}++;
c9e77dbb 358 push @attrs => $meta->get_attribute($attr_name);
e16da3e6 359 }
360 }
361 return @attrs;
362}
2eb717d5 363
52e8a34c 364# Class attributes
365
366sub add_package_variable {
367 my ($self, $variable, $initial_value) = @_;
368 (defined $variable && $variable =~ /^[\$\@\%]/)
369 || confess "variable name does not have a sigil";
370
371 my ($sigil, $name) = ($variable =~ /^(.)(.*)$/);
372 if (defined $initial_value) {
373 no strict 'refs';
374 *{$self->name . '::' . $name} = $initial_value;
375 }
376 else {
377 eval $sigil . $self->name . '::' . $name;
378 confess "Could not create package variable ($variable) because : $@" if $@;
379 }
380}
381
382sub has_package_variable {
383 my ($self, $variable) = @_;
384 (defined $variable && $variable =~ /^[\$\@\%]/)
385 || confess "variable name does not have a sigil";
386 my ($sigil, $name) = ($variable =~ /^(.)(.*)$/);
387 no strict 'refs';
388 defined ${$self->name . '::'}{$name} ? 1 : 0;
389}
390
391sub get_package_variable {
392 my ($self, $variable) = @_;
393 (defined $variable && $variable =~ /^[\$\@\%]/)
394 || confess "variable name does not have a sigil";
395 my ($sigil, $name) = ($variable =~ /^(.)(.*)$/);
396 no strict 'refs';
397 # try to fetch it first,.. see what happens
398 eval '\\' . $sigil . $self->name . '::' . $name;
399 confess "Could not get the package variable ($variable) because : $@" if $@;
400 # if we didn't die, then we can return it
401 # NOTE:
402 # this is not ideal, better suggestions are welcome
403 eval '\\' . $sigil . $self->name . '::' . $name;
404}
405
406sub remove_package_variable {
407 my ($self, $variable) = @_;
408 (defined $variable && $variable =~ /^[\$\@\%]/)
409 || confess "variable name does not have a sigil";
410 my ($sigil, $name) = ($variable =~ /^(.)(.*)$/);
411 no strict 'refs';
412 delete ${$self->name . '::'}{$name};
413}
414
8b978dd5 4151;
416
417__END__
418
419=pod
420
421=head1 NAME
422
423Class::MOP::Class - Class Meta Object
424
425=head1 SYNOPSIS
426
fe122940 427 # use this for introspection ...
428
429 package Foo;
430 sub meta { Class::MOP::Class->initialize(__PACKAGE__) }
431
432 # elsewhere in the code ...
433
434 # add a method to Foo ...
435 Foo->meta->add_method('bar' => sub { ... })
436
437 # get a list of all the classes searched
438 # the method dispatcher in the correct order
439 Foo->meta->class_precedence_list()
440
441 # remove a method from Foo
442 Foo->meta->remove_method('bar');
443
444 # or use this to actually create classes ...
445
446 Class::MOP::Class->create('Bar' => '0.01' => (
447 superclasses => [ 'Foo' ],
448 attributes => [
449 Class::MOP:::Attribute->new('$bar'),
450 Class::MOP:::Attribute->new('$baz'),
451 ],
452 methods => {
453 calculate_bar => sub { ... },
454 construct_baz => sub { ... }
455 }
456 ));
457
8b978dd5 458=head1 DESCRIPTION
459
fe122940 460This is the largest and currently most complex part of the Perl 5
461meta-object protocol. It controls the introspection and
462manipulation of Perl 5 classes (and it can create them too). The
463best way to understand what this module can do, is to read the
464documentation for each of it's methods.
465
552e3d24 466=head1 METHODS
467
2eb717d5 468=head2 Self Introspection
469
470=over 4
471
472=item B<meta>
473
fe122940 474This will return a B<Class::MOP::Class> instance which is related
475to this class. Thereby allowing B<Class::MOP::Class> to actually
476introspect itself.
477
478As with B<Class::MOP::Attribute>, B<Class::MOP> will actually
479bootstrap this module by installing a number of attribute meta-objects
480into it's metaclass. This will allow this class to reap all the benifits
481of the MOP when subclassing it.
2eb717d5 482
483=back
484
552e3d24 485=head2 Class construction
486
a2e85e6c 487These methods will handle creating B<Class::MOP::Class> objects,
488which can be used to both create new classes, and analyze
489pre-existing classes.
552e3d24 490
491This module will internally store references to all the instances
492you create with these methods, so that they do not need to be
493created any more than nessecary. Basically, they are singletons.
494
495=over 4
496
497=item B<create ($package_name, ?$package_version,
a2e85e6c 498 superclasses =E<gt> ?@superclasses,
499 methods =E<gt> ?%methods,
500 attributes =E<gt> ?%attributes)>
552e3d24 501
a2e85e6c 502This returns a B<Class::MOP::Class> object, bringing the specified
552e3d24 503C<$package_name> into existence and adding any of the
504C<$package_version>, C<@superclasses>, C<%methods> and C<%attributes>
505to it.
506
507=item B<initialize ($package_name)>
508
a2e85e6c 509This initializes and returns returns a B<Class::MOP::Class> object
510for a given a C<$package_name>.
511
512=item B<construct_class_instance ($package_name)>
513
514This will construct an instance of B<Class::MOP::Class>, it is
515here so that we can actually "tie the knot" for B<Class::MOP::Class>
516to use C<construct_instance> once all the bootstrapping is done. This
517method is used internally by C<initialize> and should never be called
518from outside of that method really.
552e3d24 519
520=back
521
c9e77dbb 522=head2 Object instance construction and cloning
a2e85e6c 523
c9e77dbb 524These methods are B<entirely optional>, it is up to you whether you want
525to use them or not.
552e3d24 526
527=over 4
528
cbd9f942 529=item B<construct_instance (%params)>
552e3d24 530
c9e77dbb 531This method is used to construct an instace structure suitable for
532C<bless>-ing into your package of choice. It works in conjunction
533with the Attribute protocol to collect all applicable attributes.
534
cbd9f942 535This will construct and instance using a HASH ref as storage
552e3d24 536(currently only HASH references are supported). This will collect all
a2e85e6c 537the applicable attributes and layout out the fields in the HASH ref,
538it will then initialize them using either use the corresponding key
539in C<%params> or any default value or initializer found in the
540attribute meta-object.
727919c5 541
c9e77dbb 542=item B<clone_instance($instance, %params)>
543
544This method is a compliment of C<construct_instance> (which means if
545you override C<construct_instance>, you need to override this one too).
546
547This method will clone the C<$instance> structure created by the
548C<construct_instance> method, and apply any C<%params> passed to it
549to change the attribute values. The structure returned is (like with
550C<construct_instance>) an unC<bless>ed HASH reference, it is your
551responsibility to then bless this cloned structure into the right
552class.
553
552e3d24 554=back
555
556=head2 Informational
557
558=over 4
559
560=item B<name>
561
a2e85e6c 562This is a read-only attribute which returns the package name for the
563given B<Class::MOP::Class> instance.
552e3d24 564
565=item B<version>
566
567This is a read-only attribute which returns the C<$VERSION> of the
a2e85e6c 568package for the given B<Class::MOP::Class> instance.
552e3d24 569
570=back
571
572=head2 Inheritance Relationships
573
574=over 4
575
576=item B<superclasses (?@superclasses)>
577
578This is a read-write attribute which represents the superclass
a2e85e6c 579relationships of the class the B<Class::MOP::Class> instance is
580associated with. Basically, it can get and set the C<@ISA> for you.
552e3d24 581
343203ee 582B<NOTE:>
583Perl will occasionally perform some C<@ISA> and method caching, if
584you decide to change your superclass relationship at runtime (which
585is quite insane and very much not recommened), then you should be
586aware of this and the fact that this module does not make any
587attempt to address this issue.
588
552e3d24 589=item B<class_precedence_list>
590
a2e85e6c 591This computes the a list of all the class's ancestors in the same order
592in which method dispatch will be done. This is similair to
593what B<Class::ISA::super_path> does, but we don't remove duplicate names.
552e3d24 594
595=back
596
597=head2 Methods
598
599=over 4
600
2e41896e 601=item B<method_metaclass>
602
552e3d24 603=item B<add_method ($method_name, $method)>
604
605This will take a C<$method_name> and CODE reference to that
a2e85e6c 606C<$method> and install it into the class's package.
552e3d24 607
a2e85e6c 608B<NOTE>:
609This does absolutely nothing special to C<$method>
552e3d24 610other than use B<Sub::Name> to make sure it is tagged with the
611correct name, and therefore show up correctly in stack traces and
612such.
613
614=item B<has_method ($method_name)>
615
a2e85e6c 616This just provides a simple way to check if the class implements
552e3d24 617a specific C<$method_name>. It will I<not> however, attempt to check
a2e85e6c 618if the class inherits the method (use C<UNIVERSAL::can> for that).
552e3d24 619
620This will correctly handle functions defined outside of the package
621that use a fully qualified name (C<sub Package::name { ... }>).
622
623This will correctly handle functions renamed with B<Sub::Name> and
624installed using the symbol tables. However, if you are naming the
625subroutine outside of the package scope, you must use the fully
626qualified name, including the package name, for C<has_method> to
627correctly identify it.
628
629This will attempt to correctly ignore functions imported from other
630packages using B<Exporter>. It breaks down if the function imported
631is an C<__ANON__> sub (such as with C<use constant>), which very well
632may be a valid method being applied to the class.
633
634In short, this method cannot always be trusted to determine if the
635C<$method_name> is actually a method. However, it will DWIM about
a2e85e6c 63690% of the time, so it's a small trade off I think.
552e3d24 637
638=item B<get_method ($method_name)>
639
640This will return a CODE reference of the specified C<$method_name>,
641or return undef if that method does not exist.
642
643=item B<remove_method ($method_name)>
644
a2e85e6c 645This will attempt to remove a given C<$method_name> from the class.
552e3d24 646It will return the CODE reference that it has removed, and will
647attempt to use B<Sub::Name> to clear the methods associated name.
648
649=item B<get_method_list>
650
651This will return a list of method names for all I<locally> defined
652methods. It does B<not> provide a list of all applicable methods,
653including any inherited ones. If you want a list of all applicable
654methods, use the C<compute_all_applicable_methods> method.
655
656=item B<compute_all_applicable_methods>
657
a2e85e6c 658This will return a list of all the methods names this class will
659respond to, taking into account inheritance. The list will be a list of
552e3d24 660HASH references, each one containing the following information; method
661name, the name of the class in which the method lives and a CODE
662reference for the actual method.
663
664=item B<find_all_methods_by_name ($method_name)>
665
666This will traverse the inheritence hierarchy and locate all methods
667with a given C<$method_name>. Similar to
668C<compute_all_applicable_methods> it returns a list of HASH references
669with the following information; method name (which will always be the
670same as C<$method_name>), the name of the class in which the method
671lives and a CODE reference for the actual method.
672
673The list of methods produced is a distinct list, meaning there are no
674duplicates in it. This is especially useful for things like object
675initialization and destruction where you only want the method called
676once, and in the correct order.
677
678=back
679
680=head2 Attributes
681
682It should be noted that since there is no one consistent way to define
683the attributes of a class in Perl 5. These methods can only work with
684the information given, and can not easily discover information on
a2e85e6c 685their own. See L<Class::MOP::Attribute> for more details.
552e3d24 686
687=over 4
688
2e41896e 689=item B<attribute_metaclass>
690
552e3d24 691=item B<add_attribute ($attribute_name, $attribute_meta_object)>
692
a2e85e6c 693This stores a C<$attribute_meta_object> in the B<Class::MOP::Class>
694instance associated with the given class, and associates it with
695the C<$attribute_name>. Unlike methods, attributes within the MOP
696are stored as meta-information only. They will be used later to
697construct instances from (see C<construct_instance> above).
552e3d24 698More details about the attribute meta-objects can be found in the
a2e85e6c 699L<Class::MOP::Attribute> or the L<Class::MOP/The Attribute protocol>
700section.
701
702It should be noted that any accessor, reader/writer or predicate
703methods which the C<$attribute_meta_object> has will be installed
704into the class at this time.
552e3d24 705
706=item B<has_attribute ($attribute_name)>
707
a2e85e6c 708Checks to see if this class has an attribute by the name of
552e3d24 709C<$attribute_name> and returns a boolean.
710
711=item B<get_attribute ($attribute_name)>
712
713Returns the attribute meta-object associated with C<$attribute_name>,
714if none is found, it will return undef.
715
716=item B<remove_attribute ($attribute_name)>
717
718This will remove the attribute meta-object stored at
719C<$attribute_name>, then return the removed attribute meta-object.
720
a2e85e6c 721B<NOTE:>
722Removing an attribute will only affect future instances of
552e3d24 723the class, it will not make any attempt to remove the attribute from
724any existing instances of the class.
725
a2e85e6c 726It should be noted that any accessor, reader/writer or predicate
727methods which the attribute meta-object stored at C<$attribute_name>
728has will be removed from the class at this time. This B<will> make
729these attributes somewhat inaccessable in previously created
730instances. But if you are crazy enough to do this at runtime, then
731you are crazy enough to deal with something like this :).
732
552e3d24 733=item B<get_attribute_list>
734
735This returns a list of attribute names which are defined in the local
736class. If you want a list of all applicable attributes for a class,
737use the C<compute_all_applicable_attributes> method.
738
739=item B<compute_all_applicable_attributes>
740
c9e77dbb 741This will traverse the inheritance heirachy and return a list of all
742the applicable attributes for this class. It does not construct a
743HASH reference like C<compute_all_applicable_methods> because all
744that same information is discoverable through the attribute
745meta-object itself.
552e3d24 746
747=back
748
52e8a34c 749=head2 Package Variables
750
751Since Perl's classes are built atop the Perl package system, it is
752fairly common to use package scoped variables for things like static
753class variables. The following methods are convience methods for
754the creation and inspection of package scoped variables.
755
756=over 4
757
758=item B<add_package_variable ($variable_name, ?$initial_value)>
759
760Given a C<$variable_name>, which must contain a leading sigil, this
761method will create that variable within the package which houses the
762class. It also takes an optional C<$initial_value>, which must be a
763reference of the same type as the sigil of the C<$variable_name>
764implies.
765
766=item B<get_package_variable ($variable_name)>
767
768This will return a reference to the package variable in
769C<$variable_name>.
770
771=item B<has_package_variable ($variable_name)>
772
773Returns true (C<1>) if there is a package variable defined for
774C<$variable_name>, and false (C<0>) otherwise.
775
776=item B<remove_package_variable ($variable_name)>
777
778This will attempt to remove the package variable at C<$variable_name>.
779
780=back
781
8b978dd5 782=head1 AUTHOR
783
a2e85e6c 784Stevan Little E<lt>stevan@iinteractive.comE<gt>
8b978dd5 785
786=head1 COPYRIGHT AND LICENSE
787
788Copyright 2006 by Infinity Interactive, Inc.
789
790L<http://www.iinteractive.com>
791
792This library is free software; you can redistribute it and/or modify
793it under the same terms as Perl itself.
794
795=cut