X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FPackage.pm;h=e5ed66ffccde5ec9f30ad64cf79dccff36172394;hb=c2310a31813d069ab9c12ff55de27817a3899b61;hp=43e42f95d2082969b26c69ed04bb525d153232ee;hpb=eca95e0476ae5a66144c4fd1f4a23c2ba4bdbf26;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Package.pm b/lib/Class/MOP/Package.pm index 43e42f9..e5ed66f 100644 --- a/lib/Class/MOP/Package.pm +++ b/lib/Class/MOP/Package.pm @@ -4,11 +4,10 @@ package Class::MOP::Package; use strict; use warnings; -use B; use Scalar::Util 'blessed'; use Carp 'confess'; -our $VERSION = '0.78'; +our $VERSION = '0.89'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -128,13 +127,13 @@ sub add_package_symbol { my ($name, $sigil, $type) = ref $variable eq 'HASH' ? @{$variable}{qw[name sigil type]} - : $self->_deconstruct_variable_name($variable); + : $self->_deconstruct_variable_name($variable); my $pkg = $self->{'package'}; no strict 'refs'; - no warnings 'redefine', 'misc'; - *{$pkg . '::' . $name} = ref $initial_value ? $initial_value : \$initial_value; + no warnings 'redefine', 'misc', 'prototype'; + *{$pkg . '::' . $name} = ref $initial_value ? $initial_value : \$initial_value; } sub remove_package_glob { @@ -156,24 +155,19 @@ sub has_package_symbol { return 0 unless exists $namespace->{$name}; - # FIXME: - # For some really stupid reason - # a typeglob will have a default - # value of \undef in the SCALAR - # slot, so we need to work around - # this. Which of course means that - # if you put \undef in your scalar - # then this is broken. - - if (ref($namespace->{$name}) eq 'SCALAR') { - return ($type eq 'CODE'); - } - elsif ($type eq 'SCALAR') { - my $val = *{$namespace->{$name}}{$type}; - return defined(${$val}); - } - else { - defined(*{$namespace->{$name}}{$type}); + my $entry_ref = \$namespace->{$name}; + if (ref($entry_ref) eq 'GLOB') { + if ($type eq 'SCALAR') { + return defined(${ *{$entry_ref}{SCALAR} }); + } + else { + return defined(*{$entry_ref}{$type}); + } + } + else { + # a symbol table entry can be -1 (stub), string (stub with prototype), + # or reference (constant) + return $type eq 'CODE'; } } @@ -186,21 +180,24 @@ sub get_package_symbol { my $namespace = $self->namespace; + # FIXME $self->add_package_symbol($variable) unless exists $namespace->{$name}; - if (ref($namespace->{$name}) eq 'SCALAR') { - if ($type eq 'CODE') { + my $entry_ref = \$namespace->{$name}; + + if (ref($entry_ref) eq 'GLOB') { + return *{$entry_ref}{$type}; + } + else{ + if($type eq 'CODE'){ no strict 'refs'; - return \&{$self->name.'::'.$name}; + return \&{$self->name . '::' . $name}; } - else { + else{ return undef; } } - else { - return *{$namespace->{$name}}{$type}; - } } sub remove_package_symbol { @@ -287,83 +284,84 @@ Class::MOP::Package - Package Meta Object =head1 DESCRIPTION -This is an abstraction of a Perl 5 package, it is a superclass of -L and provides all of the symbol table -introspection methods. - -=head1 INHERITANCE - -B is a subclass of L +The Package Protocol provides an abstraction of a Perl 5 package. A +package is basically namespace, and this module provides methods for +looking at and changing that namespace's symbol table. =head1 METHODS =over 4 -=item B +=item B<< Class::MOP::Package->initialize($package_name) >> + +This method creates a new C instance which +represents specified package. If an existing metaclass object exists +for the package, that will be returned instead. + +=item B<< Class::MOP::Package->reinitialize($package_name) >> -Returns a metaclass for this package. +This method forcibly removes any existing metaclass for the package +before calling C -=item B +Do not call this unless you know what you are doing. -This will initialize a Class::MOP::Package instance which represents -the package of C<$package_name>. +=item B<< $metapackage->name >> -=item B +This is returns the package's name, as passed to the constructor. -This removes the old metaclass, and creates a new one in it's place. -Do B use this unless you really know what you are doing, it could -very easily make a very large mess of your program. +=item B<< $metapackage->namespace >> -=item B +This returns a hash reference to the package's symbol table. The keys +are symbol names and the values are typeglob references. -This is a read-only attribute which returns the package name for the -given instance. +=item B<< $metapackage->add_package_symbol($variable_name, $initial_value) >> -=item B +This method accepts a variable name and an optional initial value. The +C<$variable_name> must contain a leading sigil. -This returns a HASH reference to the symbol table. The keys of the -HASH are the symbol names, and the values are typeglob references. +This method creates the variable in the package's symbol table, and +sets it to the initial value if one was provided. -=item B +=item B<< $metapackage->get_package_symbol($variable_name) >> -Given a C<$variable_name>, which must contain a leading sigil, this -method will create that variable within the package which houses the -class. It also takes an optional C<$initial_value>, which must be a -reference of the same type as the sigil of the C<$variable_name> -implies. +Given a variable name, this method returns the variable as a reference +or undef if it does not exist. The C<$variable_name> must contain a +leading sigil. -=item B +=item B<< $metapackage->has_package_symbol($variable_name) >> -This will return a reference to the package variable in -C<$variable_name>. +Returns true if there is a package variable defined for +C<$variable_name>. The C<$variable_name> must contain a leading sigil. -=item B +=item B<< $metapackage->remove_package_symbol($variable_name) >> -Returns true (C<1>) if there is a package variable defined for -C<$variable_name>, and false (C<0>) otherwise. +This will remove the package variable specified C<$variable_name>. The +C<$variable_name> must contain a leading sigil. -=item B +=item B<< $metapackage->remove_package_glob($glob_name) >> -This will attempt to remove the package variable at C<$variable_name>. +Given the name of a glob, this will remove that glob from the +package's symbol table. Glob names do not include a sigil. Removing +the glob removes all variables and subroutines with the specified +name. -=item B +=item B<< $metapackage->list_all_package_symbols($type_filter) >> -This will attempt to remove the entire typeglob associated with -C<$glob_name> from the package. +This will list all the glob names associated with the current +package. These names do not have leading sigils. -=item B +You can provide an optional type filter, which should be one of +'SCALAR', 'ARRAY', 'HASH', or 'CODE'. -This will list all the glob names associated with the current package. -By inspecting the globs returned you can discern all the variables in -the package. +=item B<< $metapackage->get_all_package_symbols($type_filter) >> -By passing a C<$type_filter>, you can limit the list to only those -which match the filter (either SCALAR, ARRAY, HASH or CODE). +This works much like C, but it returns a +hash reference. The keys are glob names and the values are references +to the value for that name. -=item B +=item B<< Class::MOP::Package->meta >> -Works exactly like C but returns a HASH of -name => thing mapping instead of just an ARRAY of names. +This will return a L instance for this class. =back @@ -373,7 +371,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2008 by Infinity Interactive, Inc. +Copyright 2006-2009 by Infinity Interactive, Inc. L