From: Stevan Little Date: Tue, 14 Feb 2006 19:50:14 +0000 (+0000) Subject: moving the scala mixins to a test only X-Git-Tag: 0_10~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ea2630602772744cd78148ca0933b10c141d88c9;p=gitmo%2FClass-MOP.git moving the scala mixins to a test only --- diff --git a/Build.PL b/Build.PL index 023fd21..ffdec51 100644 --- a/Build.PL +++ b/Build.PL @@ -11,7 +11,6 @@ my $build = Module::Build->new( 'Carp' => '0.01', 'B' => '1.09', 'Clone' => '0.18', - 'SUPER' => '1.11', }, optional => { }, diff --git a/Changes b/Changes index 4b0a9f3..3ff423c 100644 --- a/Changes +++ b/Changes @@ -2,20 +2,14 @@ Revision history for Perl extension Class-MOP. 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 diff --git a/MANIFEST b/MANIFEST index 913e996..a81b6ef 100644 --- a/MANIFEST +++ b/MANIFEST @@ -2,6 +2,8 @@ Build.PL Changes MANIFEST MANIFEST.SKIP +Makefile.PL +META.yml README examples/AttributesWithHistory.pod examples/ClassEncapsulatedAttributes.pod @@ -31,6 +33,7 @@ t/020_attribute.t 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 @@ -38,7 +41,7 @@ t/103_Perl6Attribute_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 diff --git a/lib/Class/MOP/Class.pm b/lib/Class/MOP/Class.pm index 64b8f4e..c109368 100644 --- a/lib/Class/MOP/Class.pm +++ b/lib/Class/MOP/Class.pm @@ -493,34 +493,6 @@ sub remove_package_variable { 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__ diff --git a/t/010_self_introspection.t b/t/010_self_introspection.t index 5a98408..87416dd 100644 --- a/t/010_self_introspection.t +++ b/t/010_self_introspection.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 119; +use Test::More tests => 117; use Test::Exception; BEGIN { @@ -36,8 +36,6 @@ my @methods = qw( get_attribute_list get_attribute_map compute_all_applicable_attributes add_package_variable get_package_variable has_package_variable remove_package_variable - - mixin ); is_deeply([ sort @methods ], [ sort $meta->get_method_list ], '... got the correct method list'); diff --git a/t/050_class_mixin_composition.t b/t/050_class_mixin_composition.t index 56e65ee..290747c 100644 --- a/t/050_class_mixin_composition.t +++ b/t/050_class_mixin_composition.t @@ -3,11 +3,23 @@ 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 @@ -45,6 +57,57 @@ code above is well-formed. =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; @@ -98,7 +161,7 @@ code above is well-formed. package ColoredPoint3D; our @ISA = ('Point3D'); - __PACKAGE__->meta->mixin('ColoredPoint2D'); + ::with('ColoredPoint2D'); }