Merge branch 'stable'
[gitmo/Class-MOP.git] / lib / Class / MOP / Package.pm
CommitLineData
2243a22b 1
2package Class::MOP::Package;
3
4use strict;
5use warnings;
6
812d58f9 7use Scalar::Util 'blessed', 'reftype';
6d5355c3 8use Carp 'confess';
407a4276 9use Package::Stash;
2243a22b 10
bd2550f8 11our $VERSION = '1.12';
d519662a 12$VERSION = eval $VERSION;
f0480c45 13our $AUTHORITY = 'cpan:STEVAN';
2243a22b 14
f197afa6 15use base 'Class::MOP::Object';
6e57504d 16
6d5355c3 17# creation ...
18
19sub initialize {
3be6bc1c 20 my ( $class, @args ) = @_;
21
22 unshift @args, "package" if @args % 2;
23
24 my %options = @args;
25 my $package_name = $options{package};
26
27
9d6dce77 28 # we hand-construct the class
29 # until we can bootstrap it
a19fcb5b 30 if ( my $meta = Class::MOP::get_metaclass_by_name($package_name) ) {
973de492 31 return $meta;
a19fcb5b 32 } else {
973de492 33 my $meta = ( ref $class || $class )->_new({
34 'package' => $package_name,
11ac821d 35 %options,
973de492 36 });
973de492 37 Class::MOP::store_metaclass_by_name($package_name, $meta);
a19fcb5b 38
973de492 39 return $meta;
a19fcb5b 40 }
41}
42
43sub reinitialize {
3be6bc1c 44 my ( $class, @args ) = @_;
45
46 unshift @args, "package" if @args % 2;
47
48 my %options = @args;
3eda22f8 49 my $package_name = delete $options{package};
3be6bc1c 50
7975280a 51 (defined $package_name && $package_name
52 && (!blessed $package_name || $package_name->isa('Class::MOP::Package')))
53 || confess "You must pass a package name or an existing Class::MOP::Package instance";
54
55 $package_name = $package_name->name
56 if blessed $package_name;
3be6bc1c 57
a19fcb5b 58 Class::MOP::remove_metaclass_by_name($package_name);
3be6bc1c 59
3eda22f8 60 $class->initialize($package_name, %options); # call with first arg form for compat
682655a3 61}
62
63sub _new {
0bfc85b8 64 my $class = shift;
812d58f9 65
ec9e38e5 66 return Class::MOP::Class->initialize($class)->new_object(@_)
812d58f9 67 if $class ne __PACKAGE__;
682655a3 68
ec9e38e5 69 my $params = @_ == 1 ? $_[0] : {@_};
70
71 return bless {
72 package => $params->{package},
73
74 # NOTE:
75 # because of issues with the Perl API
76 # to the typeglob in some versions, we
77 # need to just always grab a new
78 # reference to the hash in the accessor.
79 # Ideally we could just store a ref and
80 # it would Just Work, but oh well :\
81
82 namespace => \undef,
0bfc85b8 83
ec9e38e5 84 } => $class;
6d5355c3 85}
86
87# Attributes
88
89# NOTE:
90# all these attribute readers will be bootstrapped
91# away in the Class::MOP bootstrap section
92
407a4276 93sub _package_stash {
94 $_[0]->{_package_stash} ||= Package::Stash->new($_[0]->name)
56dcfc1a 95}
407a4276 96sub namespace {
97 $_[0]->_package_stash->namespace
a5e51f0b 98}
6d5355c3 99
a5e51f0b 100# Class attributes
6d5355c3 101
c46b802b 102# ... these functions have to touch the symbol table itself,.. yuk
103
86e1c8d8 104sub add_package_symbol {
407a4276 105 my $self = shift;
f3644f90 106 $self->_package_stash->add_symbol(@_);
86e1c8d8 107}
108
c46b802b 109sub remove_package_glob {
407a4276 110 my $self = shift;
f3644f90 111 $self->_package_stash->remove_glob(@_);
86e1c8d8 112}
113
114# ... these functions deal with stuff on the namespace level
115
116sub has_package_symbol {
407a4276 117 my $self = shift;
f3644f90 118 $self->_package_stash->has_symbol(@_);
86e1c8d8 119}
120
121sub get_package_symbol {
407a4276 122 my $self = shift;
f3644f90 123 $self->_package_stash->get_symbol(@_);
a5e51f0b 124}
6d5355c3 125
e4093599 126sub get_or_add_package_symbol {
127 my $self = shift;
f3644f90 128 $self->_package_stash->get_or_add_symbol(@_);
e4093599 129}
130
a5e51f0b 131sub remove_package_symbol {
407a4276 132 my $self = shift;
f3644f90 133 $self->_package_stash->remove_symbol(@_);
9d6dce77 134}
c0cbf4d9 135
9d6dce77 136sub list_all_package_symbols {
407a4276 137 my $self = shift;
f3644f90 138 $self->_package_stash->list_all_symbols(@_);
6d5355c3 139}
140
6b20722d 141sub get_all_package_symbols {
142 my $self = shift;
143 $self->_package_stash->get_all_symbols(@_);
144}
145
2243a22b 1461;
147
148__END__
149
150=pod
151
152=head1 NAME
153
154Class::MOP::Package - Package Meta Object
155
2243a22b 156=head1 DESCRIPTION
157
116a9f45 158The Package Protocol provides an abstraction of a Perl 5 package. A
159package is basically namespace, and this module provides methods for
160looking at and changing that namespace's symbol table.
121991f6 161
2243a22b 162=head1 METHODS
163
164=over 4
165
116a9f45 166=item B<< Class::MOP::Package->initialize($package_name) >>
167
168This method creates a new C<Class::MOP::Package> instance which
169represents specified package. If an existing metaclass object exists
170for the package, that will be returned instead.
171
7975280a 172=item B<< Class::MOP::Package->reinitialize($package) >>
2243a22b 173
116a9f45 174This method forcibly removes any existing metaclass for the package
7975280a 175before calling C<initialize>. In contrast to C<initialize>, you may
176also pass an existing C<Class::MOP::Package> instance instead of just
177a package name as C<$package>.
127d39a7 178
116a9f45 179Do not call this unless you know what you are doing.
6d5355c3 180
116a9f45 181=item B<< $metapackage->name >>
127d39a7 182
116a9f45 183This is returns the package's name, as passed to the constructor.
a19fcb5b 184
116a9f45 185=item B<< $metapackage->namespace >>
a19fcb5b 186
116a9f45 187This returns a hash reference to the package's symbol table. The keys
188are symbol names and the values are typeglob references.
6d5355c3 189
116a9f45 190=item B<< $metapackage->add_package_symbol($variable_name, $initial_value) >>
b9d9fc0b 191
116a9f45 192This method accepts a variable name and an optional initial value. The
193C<$variable_name> must contain a leading sigil.
a5e51f0b 194
116a9f45 195This method creates the variable in the package's symbol table, and
196sets it to the initial value if one was provided.
b9d9fc0b 197
116a9f45 198=item B<< $metapackage->get_package_symbol($variable_name) >>
b9d9fc0b 199
116a9f45 200Given a variable name, this method returns the variable as a reference
201or undef if it does not exist. The C<$variable_name> must contain a
202leading sigil.
b9d9fc0b 203
e4093599 204=item B<< $metapackage->get_or_add_package_symbol($variable_name) >>
205
206Given a variable name, this method returns the variable as a reference.
207If it does not exist, a default value will be generated if possible. The
208C<$variable_name> must contain a leading sigil.
209
116a9f45 210=item B<< $metapackage->has_package_symbol($variable_name) >>
6d5355c3 211
116a9f45 212Returns true if there is a package variable defined for
213C<$variable_name>. The C<$variable_name> must contain a leading sigil.
6d5355c3 214
116a9f45 215=item B<< $metapackage->remove_package_symbol($variable_name) >>
6d5355c3 216
116a9f45 217This will remove the package variable specified C<$variable_name>. The
218C<$variable_name> must contain a leading sigil.
6d5355c3 219
116a9f45 220=item B<< $metapackage->remove_package_glob($glob_name) >>
b9d9fc0b 221
116a9f45 222Given the name of a glob, this will remove that glob from the
223package's symbol table. Glob names do not include a sigil. Removing
224the glob removes all variables and subroutines with the specified
225name.
b9d9fc0b 226
116a9f45 227=item B<< $metapackage->list_all_package_symbols($type_filter) >>
b9d9fc0b 228
116a9f45 229This will list all the glob names associated with the current
230package. These names do not have leading sigils.
c46b802b 231
116a9f45 232You can provide an optional type filter, which should be one of
233'SCALAR', 'ARRAY', 'HASH', or 'CODE'.
9d6dce77 234
116a9f45 235=item B<< $metapackage->get_all_package_symbols($type_filter) >>
b9d9fc0b 236
116a9f45 237This works much like C<list_all_package_symbols>, but it returns a
238hash reference. The keys are glob names and the values are references
239to the value for that name.
92330ee2 240
116a9f45 241=item B<< Class::MOP::Package->meta >>
ae234dc6 242
116a9f45 243This will return a L<Class::MOP::Class> instance for this class.
ae234dc6 244
2243a22b 245=back
246
1a09d9cc 247=head1 AUTHORS
2243a22b 248
249Stevan Little E<lt>stevan@iinteractive.comE<gt>
250
251=head1 COPYRIGHT AND LICENSE
252
3e2c8600 253Copyright 2006-2010 by Infinity Interactive, Inc.
2243a22b 254
255L<http://www.iinteractive.com>
256
257This library is free software; you can redistribute it and/or modify
258it under the same terms as Perl itself.
259
92af7fdf 260=cut