Subject: | Inline Type Constraints don't accept stringifiable messages |
Date: | Mon, 16 Oct 2017 12:31:43 -0400 |
To: | bug-Moose [...] rt.cpan.org |
From: | Jon Rubin <jon.rubin [...] grantstreet.com> |
Inlining time constraints causes Moose to throw the wrong error when the
*message* returns an object with a stringification overload. This was not
happening on Moose 2.0402, and has been happening at least for Moose 2.1604
and the current version (2.2006).
I am using perl 5.22.2 on a Centos 6 box:
Linux pexdev002-dev3.grantstreet.com 2.6.32-696.10.3.el6.x86_64 #1 SMP Tue
Sep 26 18:14:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
Proposed fix:
Simply allow things with stringification overloads to count as strings.
package Moose::Exception::ValidationFailedForInlineTypeConstraint;
...
# Not sure of the correct way to get Str in Moose world
+use MooseX::Types::Moose qw(Str);
has 'type_constraint_message' => (
is => 'ro',
- isa => 'Str',
+ isa => Str | Moose::Util::TypeConstraints->duck_type([qw< ("" >]),
required => 1
);
Alternative Proposed fix:
This ensures that you have a string in the end, so may be safer for
backwards-compatibility. But it obscures what the original object was in
reporting errors ('successful exception' instead of '123' in the
reproduction case below), and encourages coercing to the Str builtin, which
you discourage.
package Moose::Exception::ValidationFailedForInlineTypeConstraint;
...
has 'type_constraint_message' => (
is => 'ro',
isa => 'Str',
+ coerce => 1,
required => 1
);
Reproduction Case:
# Old Moose (2.0402)
# $ perl /var/tmp/moose_and_magic_strings.pl
# Attribute (validation_fail) does not pass the type constraint
because: successful exception at constructor Bad::Moose::new (defined at
/var/tmp/moose_and_magic_strings.pl line 28) line 31.
# Bad::Moose::new('Bad::Moose', 'validation_fail', 123) called at
/var/tmp/moose_and_magic_strings.pl line 32
#
# New Moose (2.1604)
# $ perl /var/tmp/moose_and_magic_strings.pl
# Attribute (type_constraint_message) does not pass the type
constraint because: Validation failed for 'Str' with value
String::Object=HASH(0x2e2da48) at
/usr/local/perl/active/lib/perl5/x86_64-linux/Moose/Object.pm line 24
#
Moose::Object::new('Moose::Exception::ValidationFailedForInlineTypeConstraint',
'type_constraint_message', 'String::Object=HASH(0x2e2da48)', 'class_name',
'Bad::Moose', 'attribute_name', 'validation_fail', 'value', 123) called at
constructor Bad::Moose::new (defined at /var/tmp/moose_and_magic_strings.pl
line 28) line 31
# Bad::Moose::new('Bad::Moose', 'validation_fail', 123) called at
/var/tmp/moose_and_magic_strings.pl line 32
package String::Object;
use overload '""' => \&as_string, fallback => 1;
sub new {
my $self = bless {}, __PACKAGE__;
}
sub as_string { 'successful exception' }
package Bad::Moose::Classes;
use Moose;
use MooseX::Types::Moose qw( Str );
use MooseX::Types -declare => [ 'AlwaysFail', 'StringObject' ];
subtype AlwaysFail,
as Str,
where { 0 },
message { String::Object->new };
class_type StringObject, { class => 'String::Object' };
coerce Str, from StringObject, via { 'coerced' };
package Bad::Moose;
use Moose;
has validation_fail => (
is => 'ro',
isa => 'AlwaysFail',
);
__PACKAGE__->meta->make_immutable; # This is the key line
package main;
Bad::Moose->new( validation_fail => '123' );
--
Jon Rubin
Grant Street Group
Ph: (412) 391-5555, Ext. 1323