0.07
- adding more tests
- - test for compatability with Class::C3
- - added SUPER as a dependency (because we need runtime
- dispatching of SUPER calls for mixins)
* Class::MOP
- no longer optionally exports to UNIVERSAL::meta or
creates a custom metaclass generator, use the
metaclass pragma instead.
- * Class::MOP::Class
- - adding in &mixin method to do Scala style mixins
-
* examples/
- - fixing the AttributesWithHistory example, it was broken
+ - fixing the AttributesWithHistory example, it was broken.
0.06 Thurs Feb. 9, 2006
* metaclass
Changes
MANIFEST
MANIFEST.SKIP
+Makefile.PL
+META.yml
README
examples/AttributesWithHistory.pod
examples/ClassEncapsulatedAttributes.pod
t/030_method.t
t/040_metaclass.t
t/041_metaclass_incompatability.t
+t/050_class_mixin_composition.t
t/100_BinaryTree_test.t
t/101_InstanceCountingClass_test.t
t/102_InsideOutClass_test.t
t/104_AttributesWithHistory_test.t
t/105_ClassEncapsulatedAttributes_test.t
t/106_LazyClass_test.t
+t/200_Class_C3_compatibility.t
t/pod.t
t/pod_coverage.t
t/lib/BinaryTree.pm
-Makefile.PL
delete ${$self->name . '::'}{$name};
}
-# class mixins
-
-sub mixin {
- my ($self, $mixin) = @_;
- $mixin = $self->initialize($mixin)
- unless blessed($mixin);
-
- my @attributes = map {
- $mixin->get_attribute($_)->clone()
- } $mixin->get_attribute_list;
-
- my %methods = map {
- my $method = $mixin->get_method($_);
- (blessed($method) && $method->isa('Class::MOP::Attribute::Accessor'))
- ? () : ($_ => $method)
- } $mixin->get_method_list;
-
- foreach my $attr (@attributes) {
- $self->add_attribute($attr)
- unless $self->has_attribute($attr->name);
- }
-
- foreach my $method_name (keys %methods) {
- $self->alias_method($method_name => $methods{$method_name})
- unless $self->has_method($method_name);
- }
-}
-
1;
__END__
use strict;
use warnings;
-use Test::More tests => 4;
+use Test::More;
+
+BEGIN {
+ eval "use SUPER 1.10";
+ plan skip_all => "SUPER 1.10 required for this test" if $@;
+ plan tests => 4;
+}
=pod
-Scala Style Class Mixin Composition
+This test demonstrates how simple it is to create Scala Style
+Class Mixin Composition. Below is an example taken from the
+Scala web site's example section, and trancoded to Class::MOP.
+
+NOTE:
+We require SUPER for this test to handle the issue with SUPER::
+being determined at compile time.
L<http://scala.epfl.ch/intro/mixin.html>
=cut
+use Scalar::Util 'blessed';
+use Carp 'confess';
+
+sub ::with ($) {
+ # fetch the metaclass for the
+ # caller and the mixin arg
+ my $metaclass = (caller)->meta;
+ my $mixin = (shift)->meta;
+
+ # according to Scala, the
+ # the superclass of our class
+ # must be a subclass of the
+ # superclass of the mixin (see above)
+ my ($super_meta) = $metaclass->superclasses();
+ my ($super_mixin) = $mixin->superclasses();
+ ($super_meta->isa($super_mixin))
+ || confess "The superclass must extend a subclass of the superclass of the mixin";
+
+ # collect all the attributes
+ # and clone them so they can
+ # associate with the new class
+ my @attributes = map {
+ $mixin->get_attribute($_)->clone()
+ } $mixin->get_attribute_list;
+
+ my %methods = map {
+ my $method = $mixin->get_method($_);
+ # we want to ignore accessors since
+ # they will be created with the attrs
+ (blessed($method) && $method->isa('Class::MOP::Attribute::Accessor'))
+ ? () : ($_ => $method)
+ } $mixin->get_method_list;
+
+ # NOTE:
+ # I assume that locally defined methods
+ # and attributes get precedence over those
+ # from the mixin.
+
+ # add all the attributes in ....
+ foreach my $attr (@attributes) {
+ $metaclass->add_attribute($attr)
+ unless $metaclass->has_attribute($attr->name);
+ }
+
+ # add all the methods in ....
+ foreach my $method_name (keys %methods) {
+ $metaclass->alias_method($method_name => $methods{$method_name})
+ unless $metaclass->has_method($method_name);
+ }
+}
+
{
package Point2D;
use metaclass;
package ColoredPoint3D;
our @ISA = ('Point3D');
- __PACKAGE__->meta->mixin('ColoredPoint2D');
+ ::with('ColoredPoint2D');
}