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