From: Hans Dieter Pearcey Date: Wed, 24 Jun 2009 18:15:40 +0000 (-0400) Subject: die on attributes with no methods and no is => 'bare' X-Git-Tag: 0.84~45 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ae907ae0d11773f6913e16f9430e47ce6417646f;p=gitmo%2FMoose.git die on attributes with no methods and no is => 'bare' --- diff --git a/Changes b/Changes index 1d1f1df..6a7d3cb 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,11 @@ Also see Moose::Manual::Delta for more details of, and workarounds for, noteworthy changes. +0.XX + * Moose::Meta::Attribute + - When adding an attribute to a metaclass, if the attribute has no + methods associated with, it will now throw an error. (hdp) + 0.83 Tue, Jun 23, 2009 * Moose::Meta::Class - Fix _construct_instance not setting the special __MOP__ object diff --git a/lib/Moose/Meta/Attribute.pm b/lib/Moose/Meta/Attribute.pm index 6d487aa..87e60ed 100644 --- a/lib/Moose/Meta/Attribute.pm +++ b/lib/Moose/Meta/Attribute.pm @@ -290,6 +290,9 @@ sub _process_options { $options->{accessor} ||= $name; } } + elsif ($options->{is} eq 'bare') { + # do nothing, but don't complain (later) about missing methods + } else { $class->throw_error("I do not understand this option (is => " . $options->{is} . ") on attribute ($name)", data => $options->{is}); } @@ -531,6 +534,25 @@ sub get_value { ## installing accessors +sub attach_to_class { + my $self = shift; + unless ( + $self->has_accessor + || $self->has_reader + || $self->has_writer + || $self->has_handles + # init_arg? + || @{ $self->associated_methods } + || ($self->_is_metadata || '') eq 'bare' + ) { + $self->throw_error( + 'Attribute (' . $self->name . ') has no associated methods' + . ' (did you mean to provide an "is" argument?)' + ) + } + return $self->SUPER::attach_to_class(@_); +} + sub accessor_metaclass { 'Moose::Meta::Method::Accessor' } sub install_accessors { diff --git a/t/020_attributes/007_attribute_custom_metaclass.t b/t/020_attributes/007_attribute_custom_metaclass.t index de3cb5b..25c3d1b 100644 --- a/t/020_attributes/007_attribute_custom_metaclass.t +++ b/t/020_attributes/007_attribute_custom_metaclass.t @@ -76,7 +76,7 @@ use Test::Exception; } '... the attribute metaclass alias worked correctly'; ::lives_ok { - has 'bar' => (metaclass => 'Bar'); + has 'bar' => (metaclass => 'Bar', is => 'bare'); } '... the attribute metaclass alias worked correctly'; } diff --git a/t/020_attributes/009_attribute_inherited_slot_specs.t b/t/020_attributes/009_attribute_inherited_slot_specs.t index 46963b7..7903f9d 100644 --- a/t/020_attributes/009_attribute_inherited_slot_specs.t +++ b/t/020_attributes/009_attribute_inherited_slot_specs.t @@ -42,8 +42,8 @@ use Test::Exception; has 'one_last_one' => (is => 'rw', isa => 'Ref'); # this one will work here .... - has 'fail' => (isa => 'CodeRef'); - has 'other_fail'; + has 'fail' => (isa => 'CodeRef', is => 'bare'); + has 'other_fail' => (is => 'bare'); package Bar; use Moose; diff --git a/t/020_attributes/012_misc_attribute_tests.t b/t/020_attributes/012_misc_attribute_tests.t index 8d02691..b788d7c 100644 --- a/t/020_attributes/012_misc_attribute_tests.t +++ b/t/020_attributes/012_misc_attribute_tests.t @@ -17,7 +17,8 @@ use Test::Exception; documentation => q{ The 'foo' attribute is my favorite attribute in the whole wide world. - } + }, + is => 'bare', ); } @@ -256,8 +257,8 @@ use Test::Exception; use Moose; } -lives_ok { OutOfClassTest::has('foo'); } 'create attr via direct sub call'; -lives_ok { OutOfClassTest->can('has')->('bar'); } 'create attr via can'; +lives_ok { OutOfClassTest::has('foo', is => 'bare'); } 'create attr via direct sub call'; +lives_ok { OutOfClassTest->can('has')->('bar', is => 'bare'); } 'create attr via can'; ok(OutOfClassTest->meta->get_attribute('foo'), 'attr created from sub call'); ok(OutOfClassTest->meta->get_attribute('bar'), 'attr created from can'); diff --git a/t/020_attributes/022_legal_options_for_inheritance.t b/t/020_attributes/022_legal_options_for_inheritance.t index e30cc97..c44b7d1 100644 --- a/t/020_attributes/022_legal_options_for_inheritance.t +++ b/t/020_attributes/022_legal_options_for_inheritance.t @@ -26,7 +26,8 @@ use Test::More tests => 2; has 'bar' => ( metaclass => 'Bar::Meta::Attribute', - my_legal_option => sub { 'Bar' } + my_legal_option => sub { 'Bar' }, + is => 'bare', ); package Bar::B; diff --git a/t/020_attributes/024_attribute_traits_parameterized.t b/t/020_attributes/024_attribute_traits_parameterized.t index c85f187..2561b34 100644 --- a/t/020_attributes/024_attribute_traits_parameterized.t +++ b/t/020_attributes/024_attribute_traits_parameterized.t @@ -25,6 +25,7 @@ use Test::More tests => 4; }, }, ], + is => 'bare', ); } @@ -40,6 +41,7 @@ use Test::More tests => 4; }, }, ], + is => 'bare', ); } diff --git a/t/020_attributes/026_attribute_without_any_methods.t b/t/020_attributes/026_attribute_without_any_methods.t new file mode 100644 index 0000000..c6f1348 --- /dev/null +++ b/t/020_attributes/026_attribute_without_any_methods.t @@ -0,0 +1,22 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 2; + +use Moose (); +use Moose::Meta::Class; + +my $meta = Moose::Meta::Class->create_anon_class; + +#local $TODO = 'not implemented yet'; + +eval { $meta->add_attribute('foo') }; +like $@, qr/Attribute \(foo\) has no associated methods/, + 'correct error message'; + +ok( + eval { $meta->add_attribute('bar', is => 'bare'); 1 }, + 'add attribute with no methods', +) or diag $@; diff --git a/t/030_roles/017_extending_role_attrs.t b/t/030_roles/017_extending_role_attrs.t index df01d3d..e960a67 100644 --- a/t/030_roles/017_extending_role_attrs.t +++ b/t/030_roles/017_extending_role_attrs.t @@ -151,6 +151,7 @@ is_deeply($quux->quux, ["hi"], "... still has the old ArrayRef value"); for (1..3) { has "err$_" => ( isa => 'Str | Int', + is => 'bare', ); } diff --git a/t/040_type_constraints/030_class_subtypes.t b/t/040_type_constraints/030_class_subtypes.t index 95ef25e..959b007 100644 --- a/t/040_type_constraints/030_class_subtypes.t +++ b/t/040_type_constraints/030_class_subtypes.t @@ -94,6 +94,7 @@ like $isa_foo->get_message( Baz->new ), qr/^Validation failed for 'IsaFoo' faile has age => ( isa => 'Positive', + is => 'bare', ); } @@ -127,6 +128,7 @@ class_type 'Negative' => message { "$_ is not a Negative Nancy" }; has age => ( isa => 'Negative', + is => 'bare', ); } diff --git a/t/050_metaclasses/014_goto_moose_import.t b/t/050_metaclasses/014_goto_moose_import.t index 41056a9..facf3e4 100644 --- a/t/050_metaclasses/014_goto_moose_import.t +++ b/t/050_metaclasses/014_goto_moose_import.t @@ -31,7 +31,7 @@ use Test::Exception; MooseAlike1->import(); - ::lives_ok( sub { has( 'size' ) }, + ::lives_ok( sub { has( 'size', is => 'bare' ) }, 'has was exported via MooseAlike1' ); MooseAlike1->unimport(); @@ -68,7 +68,7 @@ isa_ok( Foo->meta(), 'Moose::Meta::Class' ); MooseAlike2->import(); - ::lives_ok( sub { has( 'size' ) }, + ::lives_ok( sub { has( 'size', is => 'bare' ) }, 'has was exported via MooseAlike2' ); MooseAlike2->unimport(); diff --git a/t/500_test_moose/003_test_moose_has_attribute_ok.t b/t/500_test_moose/003_test_moose_has_attribute_ok.t index 957ad33..99e69f2 100644 --- a/t/500_test_moose/003_test_moose_has_attribute_ok.t +++ b/t/500_test_moose/003_test_moose_has_attribute_ok.t @@ -14,7 +14,7 @@ BEGIN { package Foo; use Moose; - has 'foo'; + has 'foo', is => 'bare'; } { @@ -23,7 +23,7 @@ BEGIN { extends 'Foo'; - has 'bar'; + has 'bar', is => 'bare'; } diff --git a/xt/author/pod_coverage.t b/xt/author/pod_coverage.t index 3464180..f5d36ff 100644 --- a/xt/author/pod_coverage.t +++ b/xt/author/pod_coverage.t @@ -15,7 +15,12 @@ plan tests => scalar @modules; my %trustme = ( 'Moose' => ['make_immutable'], - 'Moose::Meta::Attribute' => [ 'interpolate_class', 'throw_error' ], + 'Moose::Meta::Attribute' => [ + qw( interpolate_class + throw_error + attach_to_class + ) + ], 'Moose::Meta::Class' => [ qw( check_metaclass_compatibility construct_instance