});
## --------------------------------------------------------
+## Class::MOP::Method
+
+Class::MOP::Method->meta->add_attribute(
+ Class::MOP::Attribute->new('body' => (
+ reader => 'body'
+ ))
+);
+
+## --------------------------------------------------------
+## Class::MOP::Method::Wrapped
+
+# NOTE:
+# the way this item is initialized, this
+# really does not follow the standard
+# practices of attributes, but we put
+# it here for completeness
+Class::MOP::Method::Wrapped->meta->add_attribute(
+ Class::MOP::Attribute->new('modifier_table')
+);
+
+## --------------------------------------------------------
## Now close all the Class::MOP::* classes
Class::MOP::Package ->meta->make_immutable(inline_constructor => 0);
Class::MOP::Instance ->meta->make_immutable(inline_constructor => 0);
Class::MOP::Object ->meta->make_immutable(inline_constructor => 0);
+# Class::MOP::Method subclasses
+Class::MOP::Attribute::Accessor->meta->make_immutable(inline_constructor => 0);
+Class::MOP::Method::Wrapped ->meta->make_immutable(inline_constructor => 0);
+
1;
__END__
sub add_package_symbol { confess 'Cannot call method "add_package_symbol" on an immutable instance' }
sub remove_package_symbol { confess 'Cannot call method "remove_package_symbol" on an immutable instance' }
+sub get_package_symbol {
+ my ($self, $variable) = @_;
+ my ($name, $sigil, $type) = $self->_deconstruct_variable_name($variable);
+ return *{$self->namespace->{$name}}{$type}
+ if exists $self->namespace->{$name};
+ # NOTE:
+ # we have to do this here in order to preserve
+ # perl's autovivification of variables. However
+ # we do cut off direct access to add_package_symbol
+ # as shown above.
+ $self->Class::MOP::Package::add_package_symbol($variable);
+}
+
# NOTE:
# superclasses is an accessor, so
# it just cannot be changed
=item B<remove_package_symbol>
+=back
+
+=head2 Methods which work slightly differently.
+
+=over 4
+
=item B<superclasses>
+This method becomes read-only in an immutable class.
+
+=item B<get_package_symbol>
+
+This method must handle package variable autovivification
+correctly, while still disallowing C<add_package_symbol>.
+
=back
=head2 Cached methods
use strict;
use warnings;
-use Test::More tests => 17;
+use Test::More tests => 19;
BEGIN {
use_ok('Class::MOP');
# make sure we are tracking metaclasses correctly
my %METAS = (
- 'Class::MOP::Attribute' => Class::MOP::Attribute->meta,
- 'Class::MOP::Package' => Class::MOP::Package->meta,
- 'Class::MOP::Module' => Class::MOP::Module->meta,
- 'Class::MOP::Class' => Class::MOP::Class->meta,
- 'Class::MOP::Method' => Class::MOP::Method->meta,
- 'Class::MOP::Instance' => Class::MOP::Instance->meta,
- 'Class::MOP::Object' => Class::MOP::Object->meta,
+ 'Class::MOP::Attribute' => Class::MOP::Attribute->meta,
+ 'Class::MOP::Attribute::Accessor' => Class::MOP::Attribute::Accessor->meta,
+ 'Class::MOP::Package' => Class::MOP::Package->meta,
+ 'Class::MOP::Module' => Class::MOP::Module->meta,
+ 'Class::MOP::Class' => Class::MOP::Class->meta,
+ 'Class::MOP::Method' => Class::MOP::Method->meta,
+ 'Class::MOP::Method::Wrapped' => Class::MOP::Method::Wrapped->meta,
+ 'Class::MOP::Instance' => Class::MOP::Instance->meta,
+ 'Class::MOP::Object' => Class::MOP::Object->meta,
);
ok($_->is_immutable(), '... ' . $_->name . ' is immutable') for values %METAS;
is_deeply(
[ sort { $a->name cmp $b->name } Class::MOP::get_all_metaclass_instances ],
[
- Class::MOP::Attribute->meta,
+ Class::MOP::Attribute->meta,
+ Class::MOP::Attribute::Accessor->meta,
Class::MOP::Class->meta,
Class::MOP::Instance->meta,
Class::MOP::Method->meta,
+ Class::MOP::Method::Wrapped->meta,
Class::MOP::Module->meta,
Class::MOP::Object->meta,
Class::MOP::Package->meta,
is_deeply(
[ sort { $a cmp $b } Class::MOP::get_all_metaclass_names() ],
[ qw/
- Class::MOP::Attribute
+ Class::MOP::Attribute
+ Class::MOP::Attribute::Accessor
Class::MOP::Class
Class::MOP::Instance
Class::MOP::Method
+ Class::MOP::Method::Wrapped
Class::MOP::Module
Class::MOP::Object
Class::MOP::Package
is_deeply(
[ map { $_->meta->identifier } sort { $a cmp $b } Class::MOP::get_all_metaclass_names() ],
[
- "Class::MOP::Attribute-" . $Class::MOP::Attribute::VERSION . "-cpan:STEVAN",
- "Class::MOP::Class-" . $Class::MOP::Class::VERSION . "-cpan:STEVAN",
- "Class::MOP::Instance-" . $Class::MOP::Instance::VERSION . "-cpan:STEVAN",
- "Class::MOP::Method-" . $Class::MOP::Method::VERSION . "-cpan:STEVAN",
- "Class::MOP::Module-" . $Class::MOP::Module::VERSION . "-cpan:STEVAN",
- "Class::MOP::Object-" . $Class::MOP::Object::VERSION . "-cpan:STEVAN",
- "Class::MOP::Package-" . $Class::MOP::Package::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Attribute-" . $Class::MOP::Attribute::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Attribute::Accessor-" . $Class::MOP::Attribute::Accessor::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Class-" . $Class::MOP::Class::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Instance-" . $Class::MOP::Instance::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Method-" . $Class::MOP::Method::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Method::Wrapped-" . $Class::MOP::Method::Wrapped::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Module-" . $Class::MOP::Module::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Object-" . $Class::MOP::Object::VERSION . "-cpan:STEVAN",
+ "Class::MOP::Package-" . $Class::MOP::Package::VERSION . "-cpan:STEVAN",
],
'... got all the metaclass identifiers');