From: Dave Rolsky Date: Sun, 4 Jul 2010 16:58:25 +0000 (-0500) Subject: If you pass coerce => 1 for an attr, its type must have a coercion or an error is... X-Git-Tag: 1.09~56 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2b54d2a6b7bf40c4408ffbc117f6b6d77ee35c67;p=gitmo%2FMoose.git If you pass coerce => 1 for an attr, its type must have a coercion or an error is thrown --- diff --git a/Changes b/Changes index 86403b6..319efa2 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,12 @@ Also see Moose::Manual::Delta for more details of, and workarounds for, noteworthy changes. + [API CHANGES] + + * You cannot pass "coerce => 1" for an attribute unless its type constraint + has a coercion defined. If it doesn't, an error will be thrown when the + attribute is defined. (Dave Rolsky) + [NEW FEATURES] * We no longer unimport strict and warnings when Moose, Moose::Role, or diff --git a/lib/Moose/Manual/Delta.pod b/lib/Moose/Manual/Delta.pod index 69a08b8..c1b8f57 100644 --- a/lib/Moose/Manual/Delta.pod +++ b/lib/Moose/Manual/Delta.pod @@ -20,6 +20,14 @@ send us a patch. =over 4 +=item You cannot pass C<< coerce => 1 >> unless the attribute's type constraint has a coercion + +Previously, this was accepted, and it sort of worked, except that if you +attempted to set the attribute after the object was created, you would get a +runtime error. + +Now you will get an error when you attempt to define the attribute. + =item C, C, and C no longer unimport strict and warnings This change was made in 1.05, and has now been reverted. We don't know if the diff --git a/lib/Moose/Meta/Attribute.pm b/lib/Moose/Meta/Attribute.pm index 61188a7..f82b863 100644 --- a/lib/Moose/Meta/Attribute.pm +++ b/lib/Moose/Meta/Attribute.pm @@ -322,6 +322,9 @@ sub _process_options { || $class->throw_error("You cannot have coercion without specifying a type constraint on attribute ($name)", data => $options); $class->throw_error("You cannot have a weak reference to a coerced value on attribute ($name)", data => $options) if $options->{weak_ref}; + + $options->{type_constraint}->has_coercion + || $class->throw_error("You cannot coerce an attribute ($name) unless its type has a coercion", data => $options); } if (exists $options->{trigger}) { @@ -732,10 +735,8 @@ sub _coerce_and_verify { return $val unless $self->has_type_constraint; - my $type_constraint = $self->type_constraint; - if ($self->should_coerce && $type_constraint->has_coercion) { - $val = $type_constraint->coerce($val); - } + $val = $self->type_constraint->coerce($val) + if $self->should_coerce; $self->verify_against_type_constraint($val, instance => $instance); diff --git a/lib/Moose/Meta/Method/Constructor.pm b/lib/Moose/Meta/Method/Constructor.pm index 9550412..68de04a 100644 --- a/lib/Moose/Meta/Method/Constructor.pm +++ b/lib/Moose/Meta/Method/Constructor.pm @@ -242,7 +242,7 @@ sub _generate_slot_initializer { push @source => ('my $val = $params->{\'' . $init_arg . '\'};'); if ($is_moose && $attr->has_type_constraint) { - if ($attr->should_coerce && $attr->type_constraint->has_coercion) { + if ($attr->should_coerce) { push @source => $self->_generate_type_coercion( $attr, '$type_constraints[' . $index . ']', @@ -307,7 +307,7 @@ sub _generate_type_constraint_and_coercion { return unless $attr->has_type_constraint; my @source; - if ($attr->should_coerce && $attr->type_constraint->has_coercion) { + if ($attr->should_coerce) { push @source => $self->_generate_type_coercion( $attr, '$type_constraints[' . $index . ']', diff --git a/t/020_attributes/034_bad_coerce.t b/t/020_attributes/034_bad_coerce.t new file mode 100644 index 0000000..10d234b --- /dev/null +++ b/t/020_attributes/034_bad_coerce.t @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More; +use Test::Exception; + +{ + package Foo; + + use Moose; + + ::throws_ok{ has foo => ( + is => 'ro', + isa => 'Str', + coerce => 1, + ); + } qr/\QYou cannot coerce an attribute (foo) unless its type has a coercion/, + 'Cannot coerce unless the type has a coercion'; +} + +done_testing;