MANIFEST
MANIFEST.SKIP
README
+TODO
+examples/ArrayBasedStorage.pod
examples/AttributesWithHistory.pod
examples/C3MethodDispatchOrder.pod
examples/ClassEncapsulatedAttributes.pod
lib/Class/MOP.pm
lib/Class/MOP/Attribute.pm
lib/Class/MOP/Class.pm
+lib/Class/MOP/Instance.pm
lib/Class/MOP/Method.pm
t/000_load.t
t/001_basic.t
t/031_method_modifiers.t
t/040_metaclass.t
t/041_metaclass_incompatability.t
+t/042_metaclass_incompatibility_dynamic.t
+t/043_instance_metaclass_incompatibility.t
+t/044_instance_metaclass_incompatibility_dynamic.t
t/050_scala_style_mixin_composition.t
+t/060_instance.t
+t/061_instance_inline.t
t/100_BinaryTree_test.t
t/101_InstanceCountingClass_test.t
t/102_InsideOutClass_test.t
t/105_ClassEncapsulatedAttributes_test.t
t/106_LazyClass_test.t
t/107_C3MethodDispatchOrder_test.t
+t/108_ArrayBasedStorage_test.t
t/200_Class_C3_compatibility.t
t/300_random_eval_bug.t
t/pod.t
$instance->[ $self->{slot_index_map}->{$slot_name} ] = $value;
}
-sub initialize_slot {
- my ($self, $instance, $slot_name) = @_;
- $instance->[ $self->{slot_index_map}->{$slot_name} ] = undef;
-}
-
sub is_slot_initialized {
# NOTE:
# maybe use CLOS's *special-unbound-value*
my $self = shift;
# this is always okay ...
- return if blessed($self) eq 'Class::MOP::Class';
+ return if blessed($self) eq 'Class::MOP::Class' &&
+ $self->instance_metaclass eq 'Class::MOP::Instance';
my @class_list = $self->class_precedence_list;
shift @class_list; # shift off $self->name
if (@_) {
my @supers = @_;
@{$self->name . '::ISA'} = @supers;
+ # NOTE:
+ # we need to check the metaclass
+ # compatability here so that we can
+ # be sure that the superclass is
+ # not potentially creating an issues
+ # we don't know about
+ $self->check_metaclass_compatability();
}
@{$self->name . '::ISA'};
}
sub initialize_slot {
my ($self, $instance, $slot_name) = @_;
- $instance->{$slot_name} = undef;
+ $self->set_slot_value($instance, $slot_name, undef);
}
sub initialize_all_slots {
($metaclass->isa('Class::MOP::Class'))
|| confess 'The metaclass must be derived from Class::MOP::Class';
}
- my %options = @_;
- my $package = caller();
+ my %options = @_;
+ my $package = caller();
# create a meta object so we can install &meta
my $meta = $metaclass->initialize($package => %options);
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+BEGIN {
+ use_ok('metaclass');
+}
+
+# meta classes
+{
+ package Foo::Meta;
+ use base 'Class::MOP::Class';
+
+ package Bar::Meta;
+ use base 'Class::MOP::Class';
+
+ package FooBar::Meta;
+ use base 'Foo::Meta', 'Bar::Meta';
+}
+
+$@ = undef;
+eval {
+ package Foo;
+ metaclass->import('Foo::Meta');
+};
+ok(!$@, '... Foo.meta => Foo::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar;
+ metaclass->import('Bar::Meta');
+};
+ok(!$@, '... Bar.meta => Bar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Foo::Foo;
+ metaclass->import('Bar::Meta');
+ Foo::Foo->meta->superclasses('Foo');
+};
+ok($@, '... Foo::Foo.meta => Bar::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar::Bar;
+ metaclass->import('Foo::Meta');
+ Bar::Bar->meta->superclasses('Bar');
+};
+ok($@, '... Bar::Bar.meta => Foo::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar;
+ metaclass->import('FooBar::Meta');
+ FooBar->meta->superclasses('Foo');
+};
+ok(!$@, '... FooBar.meta => FooBar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar2;
+ metaclass->import('FooBar::Meta');
+ FooBar2->meta->superclasses('Bar');
+};
+ok(!$@, '... FooBar2.meta => FooBar::Meta is compatible') || diag $@;
+
+
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+BEGIN {
+ use_ok('metaclass');
+}
+
+# meta classes
+{
+ package Foo::Meta::Instance;
+ use base 'Class::MOP::Instance';
+
+ package Bar::Meta::Instance;
+ use base 'Class::MOP::Instance';
+
+ package FooBar::Meta::Instance;
+ use base 'Foo::Meta::Instance', 'Bar::Meta::Instance';
+}
+
+$@ = undef;
+eval {
+ package Foo;
+ metaclass->import(':instance_metaclass' => 'Foo::Meta::Instance');
+};
+ok(!$@, '... Foo.meta => Foo::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar;
+ metaclass->import(':instance_metaclass' => 'Bar::Meta::Instance');
+};
+ok(!$@, '... Bar.meta => Bar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Foo::Foo;
+ use base 'Foo';
+ metaclass->import(':instance_metaclass' => 'Bar::Meta::Instance');
+};
+ok($@, '... Foo::Foo.meta => Bar::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar::Bar;
+ use base 'Bar';
+ metaclass->import(':instance_metaclass' => 'Foo::Meta::Instance');
+};
+ok($@, '... Bar::Bar.meta => Foo::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar;
+ use base 'Foo';
+ metaclass->import(':instance_metaclass' => 'FooBar::Meta::Instance');
+};
+ok(!$@, '... FooBar.meta => FooBar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar2;
+ use base 'Bar';
+ metaclass->import(':instance_metaclass' => 'FooBar::Meta::Instance');
+};
+ok(!$@, '... FooBar2.meta => FooBar::Meta is compatible') || diag $@;
+
+
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 7;
+
+BEGIN {
+ use_ok('metaclass');
+}
+
+# meta classes
+{
+ package Foo::Meta::Instance;
+ use base 'Class::MOP::Instance';
+
+ package Bar::Meta::Instance;
+ use base 'Class::MOP::Instance';
+
+ package FooBar::Meta::Instance;
+ use base 'Foo::Meta::Instance', 'Bar::Meta::Instance';
+}
+
+$@ = undef;
+eval {
+ package Foo;
+ metaclass->import(':instance_metaclass' => 'Foo::Meta::Instance');
+};
+ok(!$@, '... Foo.meta => Foo::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar;
+ metaclass->import(':instance_metaclass' => 'Bar::Meta::Instance');
+};
+ok(!$@, '... Bar.meta => Bar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Foo::Foo;
+ metaclass->import(':instance_metaclass' => 'Bar::Meta::Instance');
+ Foo::Foo->meta->superclasses('Foo');
+};
+ok($@, '... Foo::Foo.meta => Bar::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package Bar::Bar;
+ metaclass->import(':instance_metaclass' => 'Foo::Meta::Instance');
+ Bar::Bar->meta->superclasses('Bar');
+};
+ok($@, '... Bar::Bar.meta => Foo::Meta is not compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar;
+ metaclass->import(':instance_metaclass' => 'FooBar::Meta::Instance');
+ FooBar->meta->superclasses('Foo');
+};
+ok(!$@, '... FooBar.meta => FooBar::Meta is compatible') || diag $@;
+
+$@ = undef;
+eval {
+ package FooBar2;
+ metaclass->import(':instance_metaclass' => 'FooBar::Meta::Instance');
+ FooBar2->meta->superclasses('Bar');
+};
+ok(!$@, '... FooBar2.meta => FooBar::Meta is compatible') || diag $@;
+
+