From: Stevan Little Date: Sun, 24 Feb 2008 20:03:20 +0000 (+0000) Subject: has +name from role officially supported X-Git-Tag: 0_55~294 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=8d62bf6daf6f67db2ec437a045275024f9188ee3;p=gitmo%2FMoose.git has +name from role officially supported --- diff --git a/Changes b/Changes index fb9fba6..a14b044 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,16 @@ Revision history for Perl extension Moose 0.39 + * Moose + - documenting the use of '+name' with attributes + that come from recently composed roles. It makes + sense, people are using it, and so why not just + officially support it. + + * t/ + - making test for using '+name' on attributes consumed + from a role, it works and makes sense too. + * Moose::Meta::Attribute - fix handles so that it doesn't return nothing when the method cannot be found, not sure why diff --git a/lib/Moose.pm b/lib/Moose.pm index 6c48b60..4e471dd 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -601,7 +601,8 @@ a HASH ref) of the methods you want mapped. =item B %options> This is variation on the normal attibute creator C which allows you to -clone and extend an attribute from a superclass. Here is a quick example: +clone and extend an attribute from a superclass or from a role. Here is an +example of the superclass usage: package Foo; use Moose; @@ -623,6 +624,27 @@ What is happening here is that B is cloning the C attribute from its parent class B, retaining the C 'rw'> and C 'Str'> characteristics, but changing the value in C. +Here is another example, but within the context of a role: + + package Foo::Role; + use Moose::Role; + + has 'message' => ( + is => 'rw', + isa => 'Str', + default => 'Hello, I am a Foo' + ); + + package My::Foo; + use Moose; + + with 'Foo::Role'; + + has '+message' => (default => 'Hello I am My::Foo'); + +In this case, we are basically taking the attribute which the role supplied +and altering it within the bounds of this feature. + This feature is restricted somewhat, so as to try and force at least I sanity into it. You are only allowed to change the following attributes: @@ -658,6 +680,11 @@ subtype of the old type. You are allowed to B a new C definition, but you are B allowed to I one. +=item I + +You are allowed to B a new C definition, but you are B +allowed to I one. + =back =item B sub { ... }> diff --git a/lib/Moose/Meta/Attribute.pm b/lib/Moose/Meta/Attribute.pm index b7436cc..80c16cd 100644 --- a/lib/Moose/Meta/Attribute.pm +++ b/lib/Moose/Meta/Attribute.pm @@ -71,6 +71,14 @@ sub clone_and_inherit_options { $actual_options{handles} = $options{handles}; delete $options{handles}; } + + # handles can only be added, not changed + if ($options{builder}) { + confess "You can only add the 'builder' option, you cannot change it" + if $self->has_builder; + $actual_options{builder} = $options{builder}; + delete $options{builder}; + } # isa can be changed, but only if the # new type is a subtype diff --git a/t/030_roles/017_extending_role_attrs.t b/t/030_roles/017_extending_role_attrs.t new file mode 100644 index 0000000..9d8e4ac --- /dev/null +++ b/t/030_roles/017_extending_role_attrs.t @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 4; +use Test::Exception; + +BEGIN { + use_ok('Moose'); +} + +=pod + +This basically just makes sure that using +name +on role attributes works right. It is pretty simple +test really, but I wanted to have one since we are +officially supporting the feature now. + +=cut + +{ + package Foo::Role; + use Moose::Role; + + has 'bar' => ( + is => 'rw', + isa => 'Int', + default => sub { 10 }, + ); + + package Foo; + use Moose; + + with 'Foo::Role'; + + ::lives_ok { + has '+bar' => (default => sub { 100 }); + } '... extended the attribute successfully'; +} + +my $foo = Foo->new; +isa_ok($foo, 'Foo'); + +is($foo->bar, 100, '... got the extended attribute'); +