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