X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMouse.git;a=blobdiff_plain;f=lib%2FMouse%2FMeta%2FAttribute.pm;h=71a2bbdf178659ab4c40eb3d155210f13efa9a6d;hp=9ffac5257b7bfaf07f1e92ec6cd6e4cf870f6b26;hb=1372fcc0864d73696fe1b926d489b455be26229e;hpb=4ab51fb0d7f27cd9d984a6574c4a9d8f2fb68776 diff --git a/lib/Mouse/Meta/Attribute.pm b/lib/Mouse/Meta/Attribute.pm index 9ffac52..71a2bbd 100644 --- a/lib/Mouse/Meta/Attribute.pm +++ b/lib/Mouse/Meta/Attribute.pm @@ -1,11 +1,8 @@ package Mouse::Meta::Attribute; -use strict; -use warnings; +use Mouse::Util qw(:meta); # enables strict and warnings use Carp (); -use Mouse::Util qw(:meta); - use Mouse::Meta::TypeConstraint; use Mouse::Meta::Method::Accessor; @@ -83,8 +80,7 @@ sub _process_options{ $args->{type_constraint} = Mouse::Util::TypeConstraints::find_or_create_isa_type_constraint($args->{isa}); } elsif(exists $args->{does}){ - # TODO - # $args->{type_constraint} = Mouse::Util::TypeConstraints::find_or_create_does_type_constraint($args->{does}); + $args->{type_constraint} = Mouse::Util::TypeConstraints::find_or_create_does_type_constraint($args->{does}); } $tc = $args->{type_constraint}; @@ -218,17 +214,21 @@ sub interpolate_class{ my @traits; if(my $traits_ref = delete $args->{traits}){ - for (my $i = 0; $i < @{$traits_ref}; $i++) { - my $trait = Mouse::Util::resolve_metaclass_alias(Attribute => $traits_ref->[$i], trait => 1); + local $@; + eval{ + for (my $i = 0; $i < @{$traits_ref}; $i++) { + my $trait = Mouse::Util::resolve_metaclass_alias(Attribute => $traits_ref->[$i], trait => 1); - next if $class->does($trait); + next if $class->does($trait); - push @traits, $trait; + push @traits, $trait; - # are there options? - push @traits, $traits_ref->[++$i] - if ref($traits_ref->[$i+1]); - } + # are there options? + push @traits, $traits_ref->[++$i] + if ref($traits_ref->[$i+1]); + } + }; + warn "Fatal error in traits: $@" if _MOUSE_VERBOSE; if (@traits) { $class = Mouse::Meta::Class->create_anon_class( @@ -252,7 +252,7 @@ sub canonicalize_args{ # DEPRECATED return %args; } -sub create { +sub create { # DEPRECATED my ($self, $class, $name, %args) = @_; Carp::cluck("$self->create has been deprecated." @@ -267,15 +267,12 @@ sub _coerce_and_verify { my($self, $value, $instance) = @_; my $type_constraint = $self->{type_constraint}; - - return $value if !$type_constraint; + return $value if !defined $type_constraint; if ($self->should_coerce && $type_constraint->has_coercion) { $value = $type_constraint->coerce($value); } - return $value if $type_constraint->check($value); - $self->verify_against_type_constraint($value); return $value; @@ -285,7 +282,7 @@ sub verify_against_type_constraint { my ($self, $value) = @_; my $type_constraint = $self->{type_constraint}; - return 1 if !$type_constraint;; + return 1 if !$type_constraint; return 1 if $type_constraint->check($value); $self->verify_type_constraint_error($self->name, $value, $type_constraint); @@ -293,7 +290,8 @@ sub verify_against_type_constraint { sub verify_type_constraint_error { my($self, $name, $value, $type) = @_; - $self->throw_error("Attribute ($name) does not pass the type constraint because: " . $type->get_message($value)); + $self->throw_error("Attribute ($name) does not pass the type constraint because: " + . $type->get_message($value)); } sub coerce_constraint { # DEPRECATED @@ -342,10 +340,10 @@ sub get_parent_args { # DEPRECATED } -sub get_read_method { # DEPRECATED +sub get_read_method { $_[0]->{reader} || $_[0]->{accessor} } -sub get_write_method { # DEPRECATED +sub get_write_method { $_[0]->{writer} || $_[0]->{accessor} } @@ -392,6 +390,15 @@ sub _canonicalize_handles { elsif (ref($handles) eq 'ARRAY') { return map { $_ => $_ } @$handles; } + elsif (ref($handles) eq 'Regexp') { + my $class_or_role = ($self->{isa} || $self->{does}) + || $self->throw_error("Cannot delegate methods based on a Regexp without a type constraint (isa)"); + + my $meta = Mouse::Meta::Class->initialize("$class_or_role"); # "" for stringify + return map { $_ => $_ } + grep { $_ ne 'meta' && !Mouse::Object->can($_) && $_ =~ $handles } + $meta->isa('Mouse::Meta::Class') ? $meta->get_all_method_names : $meta->get_method_list; + } else { $self->throw_error("Unable to canonicalize the 'handles' option with $handles"); } @@ -459,6 +466,10 @@ __END__ Mouse::Meta::Attribute - The Mouse attribute metaclass +=head1 VERSION + +This document describes Mouse version 0.39 + =head1 METHODS =head2 C<< new(%options) -> Mouse::Meta::Attribute >> @@ -582,13 +593,13 @@ on success, otherwise Ces. Creates a new attribute in the owner class, inheriting options from parent classes. Accessors and helper methods are installed. Some error checking is done. -=head2 C<< get_read_method_ref >> - -=head2 C<< get_write_method_ref >> - -Returns the subroutine reference of a method suitable for reading or -writing the attribute's value in the associated class. These methods -always return a subroutine reference, regardless of whether or not the +=head2 C<< get_read_method_ref >> + +=head2 C<< get_write_method_ref >> + +Returns the subroutine reference of a method suitable for reading or +writing the attribute's value in the associated class. These methods +always return a subroutine reference, regardless of whether or not the attribute is read- or write-only. =head1 SEE ALSO