On Tue, Jun 14, 2011 at 3:37 PM, Jesse Luehrs <[email protected]> wrote:
> On Tue, Jun 14, 2011 at 11:03:33AM +0200, Ævar Arnfjörð Bjarmason wrote:
>> On Tue, Jun 14, 2011 at 01:56, Jesse Luehrs <[email protected]> wrote:
>> > On Mon, Jun 13, 2011 at 06:45:10PM +0200, Ævar Arnfjörð Bjarmason wrote:
>> >> On Mon, Jun 13, 2011 at 18:39, Ævar Arnfjörð Bjarmason <[email protected]>
>> >> wrote:
>> >> > For Mouse this monkeypatching would work:
>> >>
>> >> And this would work for Moose:
>> >>
>> >> package Foo;
>> >> use Moose;
>> >> {
>> >> package Moose::Meta::Attribute;
>> >>
>> >> sub verify_against_type_constraint {
>> >> my $self = shift;
>> >> my $val = shift;
>> >>
>> >> return 1 if !$self->has_type_constraint;
>> >>
>> >> my $type_constraint = $self->type_constraint;
>> >>
>> >> $type_constraint->check($val)
>> >> || Carp::cluck("Attribute ("
>> >> . $self->name
>> >> . ") does not pass the type constraint because: "
>> >> . $type_constraint->get_message($val), data => $val,
>> >> @_);
>> >> }
>> >> }
>> >>
>> >> has x => (is => "ro", isa => "Int");
>> >> my $foo = Foo->new(x => "blah");
>> >> use Data::Dumper;
>> >> print Dumper $foo;
>> >>
>> >> And give you:
>> >>
>> >> $ perl -Ilib /tmp/error.pl
>> >> Subroutine RegexpRef redefined at
>> >> lib/Moose/Util/TypeConstraints/OptimizedConstraints.pm line 35.
>> >> Subroutine verify_against_type_constraint redefined at /tmp/error.pl
>> >> line 6.
>> >> Attribute (x) does not pass the type constraint because:
>> >> Validation failed for 'Int' with value
>> >> blahdatablahinstanceFoo=HASH(0x1edadb0) at /tmp/error.pl line 14
>> >>
>> >> Moose::Meta::Attribute::verify_against_type_constraint('Moose::Meta::Attribute=HASH(0x27e0078)',
>> >> 'blah', 'instance', 'Foo=HASH(0x1edadb0)') called at
>> >> lib/Moose/Meta/Attribute.pm line 1125
>> >>
>> >> Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Attribute=HASH(0x27e0078)',
>> >> 'blah', 'Foo=HASH(0x1edadb0)') called at lib/Moose/Meta/Attribute.pm
>> >> line 485
>> >>
>> >> Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Attribute=HASH(0x27e0078)',
>> >> 'Moose::Meta::Instance=HASH(0x27ad5c0)', 'Foo=HASH(0x1edadb0)',
>> >> 'HASH(0x1ec8f90)') called at lib/Class/MOP/Class.pm line 575
>> >>
>> >> Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x266bab0)',
>> >> 'HASH(0x1ec8f90)') called at lib/Class/MOP/Class.pm line 548
>> >>
>> >> Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x266bab0)',
>> >> 'HASH(0x1ec8f90)') called at lib/Moose/Meta/Class.pm line 252
>> >>
>> >> Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x266bab0)',
>> >> 'HASH(0x1ec8f90)') called at lib/Moose/Object.pm line 22
>> >> Moose::Object::new('Foo', 'x', 'blah') called at
>> >> /tmp/error.pl line 23
>> >> $VAR1 = bless( {
>> >> 'x' => 'blah'
>> >> }, 'Foo' );
>> >>
>> >
>> > For the record, please please PLEASE don't do this. Attribute traits
>> > exist for a reason.
>>
>> How would you accomplish the same thing with attribute traits?
>
> package My::Attr::Trait;
> use Moose::Role;
>
> around verify_against_type_constraint => sub {
> my $orig = shift;
> my $self = shift;
> my ($val) = @_;
>
> return 1 if !$self->has_type_constraint;
>
> my $type_constraint = $self->type_constraint;
>
> $type_constraint->check($val)
> || Carp::cluck("Attribute ("
> . $self->name
> . ") does not pass the type constraint because: "
> . $type_constraint->get_message($val), data => $val, @_);
> };
>
> package Foo;
> use Moose;
>
> has x => (
> traits => ['My::Attr::Trait'],
> is => 'ro',
> isa => 'Int',
> );
>
> my $foo = Foo->new(x => "blah");
> use Data::Dumper;
> print Dumper $foo;
Jesse gave me permission to expand on this code and make it a CPAN
module. I finally got around to releasing it today:
https://metacpan.org/module/MooseX::Attribute::TypeConstraint::CustomizeFatal
I also pushed a rfc/mention-mx-attr-tc-customizefatal branch to the
Moose Git repository with a small change to the FAQ to mention that
yes, this is in fact possible, along with a blatant advert for my new
module. I hereby request review of that patch:
$ git show -U2 --word-diff
commit 81325e8 (HEAD, origin/rfc/mention-mx-attr-tc-customizefatal, master)
Author: Ævar Arnfjörð Bjarmason <[email protected]>
Date: Wed May 2 21:42:49 2012 +0000
Moose FAQ: Expand "Can I turn off type constraint checking?"
Expand the "Can I turn off type constraint checking?" beyond just "no"
to "you can do it with a MooseX extension". The shiny new extension
happens to be mine, but also point out that if it doesn't do what you
want it's easy to override the default behavior.
diff --git a/lib/Moose/Manual/FAQ.pod b/lib/Moose/Manual/FAQ.pod
index e4294d8..5a8cda0 100644
--- a/lib/Moose/Manual/FAQ.pod
+++ b/lib/Moose/Manual/FAQ.pod
@@ -267,5 +267,11 @@ C<NaturalLessThanTen> constraint check.
=head3 Can I turn off type constraint checking?
[-Not-]{+There's no support for it in the core of Moose+} yet.
This option may
come in a future release.
{+Meanwhile there's a L<MooseX+}
{+extension|MooseX::Attribute::TypeConstraint::CustomizeFatal> that+}
{+allows you to do this on a per-attribute basis, and if it doesn't do+}
{+what you it's easy to write one that fits your use case.+}
=head3 My coercions stopped working with recent Moose, why did you break it?