From: gfx Date: Mon, 26 Jul 2010 11:24:13 +0000 (+0900) Subject: Add illigal inheritance process (Moose 1.09 feature) X-Git-Tag: 0.64~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=df7e47294bc932e837f0548f61125e84fe56eb94;p=gitmo%2FMouse.git Add illigal inheritance process (Moose 1.09 feature) --- diff --git a/lib/Mouse/Meta/Attribute.pm b/lib/Mouse/Meta/Attribute.pm index 6d8bb3a..12dead6 100644 --- a/lib/Mouse/Meta/Attribute.pm +++ b/lib/Mouse/Meta/Attribute.pm @@ -192,20 +192,29 @@ sub _throw_type_constraint_error { ); } +sub illegal_options_for_inheritance { + return qw(is reader writer accessor clearer predicate); +} + sub clone_and_inherit_options{ my $self = shift; my $args = $self->Mouse::Object::BUILDARGS(@_); - my($attribute_class, @traits) = ref($self)->interpolate_class($args); + foreach my $illegal($self->illegal_options_for_inheritance) { + if(exists $args->{$illegal}) { + $self->throw_error("Illegal inherited option: $illegal"); + } + } - $args->{traits} = \@traits if @traits; - # do not inherit the 'handles' attribute foreach my $name(keys %{$self}){ - if(!exists $args->{$name} && $name ne 'handles'){ - $args->{$name} = $self->{$name}; + if(!exists $args->{$name}){ + $args->{$name} = $self->{$name}; # inherit from self } } + my($attribute_class, @traits) = ref($self)->interpolate_class($args); + $args->{traits} = \@traits if @traits; + # remove temporary caches foreach my $attr(keys %{$args}){ if($attr =~ /\A _/xms){ @@ -213,6 +222,11 @@ sub clone_and_inherit_options{ } } + # remove default if lazy_build => 1 + if($args->{lazy_build}) { + delete $args->{default}; + } + return $attribute_class->new($self->name, $args); } @@ -329,6 +343,10 @@ sub install_accessors{ my %handles = $attribute->_canonicalize_handles($attribute->{handles}); while(my($handle, $method_to_call) = each %handles){ + if($metaclass->has_method($handle)) { + $attribute->throw_error("You cannot overwrite a locally defined method ($handle) with a delegation"); + } + $metaclass->add_method($handle => $attribute->_make_delegation_method( $handle, $method_to_call)); diff --git a/lib/Mouse/Meta/Class.pm b/lib/Mouse/Meta/Class.pm index a21c83d..e2eb4bf 100644 --- a/lib/Mouse/Meta/Class.pm +++ b/lib/Mouse/Meta/Class.pm @@ -209,9 +209,12 @@ sub add_attribute { weaken( $attr->{associated_class} = $self ); + # install accessors first + $attr->install_accessors(); + + # then register the attribute to the metaclass $attr->{insertion_order} = keys %{ $self->{attributes} }; $self->{attributes}{$attr->name} = $attr; - $attr->install_accessors(); if(!$attr->{associated_methods} && ($attr->{is} || '') ne 'bare'){ Carp::carp(qq{Attribute ($name) of class }.$self->name diff --git a/t/020_attributes/failing/009_attribute_inherited_slot_specs.t b/t/020_attributes/009_attribute_inherited_slot_specs.t similarity index 95% rename from t/020_attributes/failing/009_attribute_inherited_slot_specs.t rename to t/020_attributes/009_attribute_inherited_slot_specs.t index 058331a..7f9cf6d 100644 --- a/t/020_attributes/failing/009_attribute_inherited_slot_specs.t +++ b/t/020_attributes/009_attribute_inherited_slot_specs.t @@ -3,12 +3,19 @@ use strict; use warnings; -use Test::More tests => 84; +use Test::More; use Test::Exception; - { + package Thing::Meta::Attribute; + use Mouse; + + extends 'Mouse::Meta::Attribute'; + around illegal_options_for_inheritance => sub { + return (shift->(@_), qw/trigger/); + }; + package Thing; use Mouse; @@ -44,7 +51,7 @@ use Test::Exception; # this one will work here .... has 'fail' => (isa => 'CodeRef', is => 'bare'); - has 'other_fail' => (is => 'bare'); + has 'other_fail' => (metaclass => 'Thing::Meta::Attribute', is => 'bare', trigger => sub { }); package Bar; use Mouse; @@ -195,15 +202,9 @@ ok(Bar->meta->has_attribute('gorch'), '... Bar has a gorch attr'); ok(Bar->meta->has_attribute('gloum'), '... Bar has a gloum attr'); ok(Bar->meta->has_attribute('bling'), '... Bar has a bling attr'); ok(Bar->meta->has_attribute('bunch_of_stuff'), '... Bar does have a bunch_of_stuff attr'); -{ -local $TODO = 'not supported'; -ok(!Bar->meta->has_attribute('blang'), '... Bar does not have a blang attr'); -} +ok(!Bar->meta->has_attribute('blang'), '... Bar has a blang attr'); ok(Bar->meta->has_attribute('fail'), '... Bar has a fail attr'); -{ -local $TODO = 'not supported'; ok(!Bar->meta->has_attribute('other_fail'), '... Bar does not have an other_fail attr'); -} isnt(Foo->meta->get_attribute('foo'), Bar->meta->get_attribute('foo'), @@ -267,4 +268,4 @@ ok(!Foo->meta->get_attribute('bling')->has_handles, ok(Bar->meta->get_attribute('bling')->has_handles, '... Bar::foo should handles'); - +done_testing;