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 <d...@tozt.net> 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 <ava...@gmail.com> > >> 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; __END__ Attribute (x) does not pass the type constraint because: Validation failed for 'Int' with value "blah"datablahblahinstanceFoo=HASH(0x14db428) at test11.pl line 13 Class::MOP::Class:::around('CODE(0x1baace0)', 'Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1e4e390)', 'blah', 'instance', 'Foo=HASH(0x14db428)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Class/MOP/Method/Wrapped.pm line 161 Class::MOP::Method::Wrapped::__ANON__('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1e4e390)', 'blah', 'instance', 'Foo=HASH(0x14db428)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Class/MOP/Method/Wrapped.pm line 91 Moose::Meta::Class::__ANON__::SERIAL::1::verify_against_type_constraint('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1e4e390)', 'blah', 'instance', 'Foo=HASH(0x14db428)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Moose/Meta/Attribute.pm line 1131 Moose::Meta::Attribute::_coerce_and_verify('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1e4e390)', 'blah', 'Foo=HASH(0x14db428)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Moose/Meta/Attribute.pm line 491 Moose::Meta::Attribute::initialize_instance_slot('Moose::Meta::Class::__ANON__::SERIAL::1=HASH(0x1e4e390)', 'Moose::Meta::Instance=HASH(0x14e5130)', 'Foo=HASH(0x14db428)', 'HASH(0x14c6fc8)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Class/MOP/Class.pm line 524 Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x1de0200)', 'HASH(0x14c6fc8)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Class/MOP/Class.pm line 497 Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x1de0200)', 'HASH(0x14c6fc8)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Moose/Meta/Class.pm line 269 Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x1de0200)', 'HASH(0x14c6fc8)') called at /home/doy/perl5/perlbrew/perls/perl-5.14.0/lib/site_perl/5.14.0/x86_64-linux/Moose/Object.pm line 28 Moose::Object::new('Foo', 'x', 'blah') called at test11.pl line 29 $VAR1 = bless( { 'x' => 'blah' }, 'Foo' ); You could also use Moose::Util::MetaRole to apply the trait to all attributes in a class by default. -doy