From: Florian Ragwitz Date: Wed, 5 May 2010 20:18:04 +0000 (+0200) Subject: Allow required versions to be specified when setting superclasses and applying roles. X-Git-Tag: 1.03~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2e7f6cf46c30d13817e127307546e37c88d28b1b;p=gitmo%2FMoose.git Allow required versions to be specified when setting superclasses and applying roles. --- diff --git a/Changes b/Changes index 6bd1f8e..c937ea0 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,11 @@ Also see Moose::Manual::Delta for more details of, and workarounds for, noteworthy changes. + [NEW FEATURES] + + * Allow specifying required versions when setting superclasses or applying + roles (Florian Ragwitz). + 1.02 Sat, May 01, 2010 [BUG FIXES] diff --git a/lib/Moose.pm b/lib/Moose.pm index 2332d27..2b1b567 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -403,10 +403,31 @@ actually Ces onto the class's C<@ISA>, whereas C will replace it. This is important to ensure that classes which do not have superclasses still properly inherit from L. +Each superclass can be followed by a hash reference with options. Currently, +only L<-version|Class::MOP/Class Loading Options> is recognized: + + extends 'My::Parent' => { -version => 0.01 }, + 'My::OtherParent' => { -version => 0.03 }; + +An exception will be thrown if the version requirements are not +satisfied. + =item B This will apply a given set of C<@roles> to the local class. +Like with C, each specified role can be followed by a hash +reference with a L<-version|Class::MOP/Class Loading Options> option: + + with 'My::Role' => { -version => 0.32 }, + 'My::Otherrole' => { -version => 0.23 }; + +The specified version requirements must be satisfied, otherwise an +exception will be thrown. + +If your role takes options or arguments, they can be passed along in the +hash reference as well. + =item B %options> This will install an attribute of a given C<$name> into the current class. If diff --git a/lib/Moose/Meta/Class.pm b/lib/Moose/Meta/Class.pm index a46c270..de7fadb 100644 --- a/lib/Moose/Meta/Class.pm +++ b/lib/Moose/Meta/Class.pm @@ -7,6 +7,7 @@ use warnings; use Class::MOP; use Carp (); +use Data::OptList; use List::Util qw( first ); use List::MoreUtils qw( any all uniq first_index ); use Scalar::Util 'weaken', 'blessed'; @@ -279,14 +280,15 @@ sub new_object { sub superclasses { my $self = shift; - my @supers = @_; - foreach my $super (@supers) { - Class::MOP::load_class($super); - my $meta = Class::MOP::class_of($super); - $self->throw_error("You cannot inherit from a Moose Role ($super)") + my $supers = Data::OptList::mkopt(\@_); + foreach my $super (@{ $supers }) { + my ($name, $opts) = @{ $super }; + Class::MOP::load_class($name, $opts); + my $meta = Class::MOP::class_of($name); + $self->throw_error("You cannot inherit from a Moose Role ($name)") if $meta && $meta->isa('Moose::Meta::Role') } - return $self->SUPER::superclasses(@supers); + return $self->SUPER::superclasses(map { $_->[0] } @{ $supers }); } ### --------------------------------------------- @@ -723,6 +725,14 @@ roles, it will be reused. cache => 1, ); +Each entry in both the C and the C option can be +followed by a hash reference with arguments. The C +option can be supplied with a L<-version|Class::MOP/Class Loading +Options> option that ensures the loaded superclass satisfies the +required version. The C option also takes the C<-version> as an +argument, but the option hash reference can also contain any other +role relevant values like exclusions or parameterized role arguments. + =item B<< $metaclass->make_immutable(%options) >> This overrides the parent's method to add a few options. Specifically, @@ -737,6 +747,15 @@ C option to false. This overrides the parent's method in order to add support for attribute triggers. +=item B<< $metaclass->superclasses(@superclasses) >> + +This is the accesssor allowing you to read or change the parents of +the class. + +Each superclass can be followed by a hash reference containing a +L<-version|Class::MOP/Class Loading Options> value. If the version +requirement is not satisfied an error will be thrown. + =item B<< $metaclass->add_override_method_modifier($name, $sub) >> This adds an C method modifier to the package. diff --git a/lib/Moose/Util.pm b/lib/Moose/Util.pm index 13c52aa..82ee65c 100644 --- a/lib/Moose/Util.pm +++ b/lib/Moose/Util.pm @@ -105,7 +105,7 @@ sub _apply_all_roles { $meta = $role->[0]; } else { - Class::MOP::load_class( $role->[0] ); + Class::MOP::load_class( $role->[0] , $role->[1] ); $meta = Class::MOP::class_of( $role->[0] ); } diff --git a/t/010_basics/002_require_superclasses.t b/t/010_basics/002_require_superclasses.t index 9757c35..ad09165 100644 --- a/t/010_basics/002_require_superclasses.t +++ b/t/010_basics/002_require_superclasses.t @@ -44,4 +44,26 @@ use Test::Exception; 'correct error when superclass could not be found'; } +{ + package Affe; + our $VERSION = 23; +} + +{ + package Tiger; + use Moose; + + ::lives_ok { extends 'Foo', Affe => { -version => 13 } } + 'extends with version requirement'; +} + +{ + package Birne; + use Moose; + + ::throws_ok { extends 'Foo', Affe => { -version => 42 } } + qr/Affe version 42 required--this is only version 23/, + 'extends with unsatisfied version requirement'; +} + done_testing; diff --git a/t/030_roles/003_apply_role.t b/t/030_roles/003_apply_role.t index d474213..e58c0e2 100644 --- a/t/030_roles/003_apply_role.t +++ b/t/030_roles/003_apply_role.t @@ -10,6 +10,8 @@ use Test::Exception; package FooRole; use Moose::Role; + our $VERSION = 23; + has 'bar' => ( is => 'rw', isa => 'FooClass' ); has 'baz' => ( is => 'ro' ); @@ -43,7 +45,13 @@ use Test::Exception; use Moose; extends 'BarClass'; - with 'FooRole'; + + ::throws_ok { with 'FooRole' => { -version => 42 } } + qr/FooRole version 42 required--this is only version 23/, + 'applying role with unsatisfied version requirement'; + + ::lives_ok { with 'FooRole' => { -version => 13 } } + 'applying role with satisfied version requirement'; sub blau {'FooClass::blau'} # << the role wraps this ...