Re: Moose Type Constraints violations to warnings?

[email protected] (Ævar Arnfjörð Bjarmason)
Newsgroups perl.moose
Message-ID <CACBZZX4tCDvTDqgiONDwy3S607O=WOqORU+nzE8O52ZwOiFbNA@mail.gmail.com>
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?
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.