bless \%args, $class;
}
-sub name { $_[0]->{name} }
-sub class { $_[0]->{class} }
-sub default { $_[0]->{default} }
-sub predicate { $_[0]->{predicate} }
-sub clearer { $_[0]->{clearer} }
-sub handles { $_[0]->{handles} }
-sub weak_ref { $_[0]->{weak_ref} }
-sub init_arg { $_[0]->{init_arg} }
+sub name { $_[0]->{name} }
+sub class { $_[0]->{class} }
+sub default { $_[0]->{default} }
+sub predicate { $_[0]->{predicate} }
+sub clearer { $_[0]->{clearer} }
+sub handles { $_[0]->{handles} }
+sub weak_ref { $_[0]->{weak_ref} }
+sub init_arg { $_[0]->{init_arg} }
+sub type_constraint { $_[0]->{type_constraint} }
+
+sub has_name { exists $_[0]->{name} }
+sub has_class { exists $_[0]->{class} }
+sub has_default { exists $_[0]->{default} }
+sub has_predicate { exists $_[0]->{predicate} }
+sub has_clearer { exists $_[0]->{clearer} }
+sub has_handles { exists $_[0]->{handles} }
+sub has_weak_ref { exists $_[0]->{weak_ref} }
+sub has_init_arg { exists $_[0]->{init_arg} }
+sub has_type_constraint { exists $_[0]->{type_constraint} }
sub generate_accessor {
my $attribute = shift;
- my $key = $attribute->{init_arg};
- my $default = $attribute->{default};
- my $trigger = $attribute->{trigger};
+ my $name = $attribute->{name};
+ my $key = $attribute->{init_arg};
+ my $default = $attribute->{default};
+ my $trigger = $attribute->{trigger};
+ my $type = $attribute->{type_constraint};
+ my $constraint = $attribute->find_type_constraint;
my $accessor = 'sub {
my $self = shift;';
if ($attribute->{is} eq 'rw') {
$accessor .= 'if (@_) {
- $self->{$key} = $_[0];';
+ local $_ = $_[0];';
+
+ if ($constraint) {
+ $accessor .= 'Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $_") unless $constraint->();'
+ }
+
+ $accessor .= '$self->{$key} = $_;';
if ($attribute->{weak_ref}) {
$accessor .= 'Scalar::Util::weaken($self->{$key});';
}
if ($trigger) {
- $accessor .= '$trigger->($self, $_[0], $attribute);';
+ $accessor .= '$trigger->($self, $_, $attribute);';
}
$accessor .= '}';
if exists($args{handles})
&& ref($args{handles}) ne 'HASH';
+ $args{type_constraint} = delete $args{isa};
+
my $attribute = $self->new(%args, name => $name, class => $class);
my $meta = $class->meta;
return $attribute;
}
+sub find_type_constraint {
+ my $self = shift;
+ my $type = $self->type_constraint;
+
+ return unless $type;
+
+ my $checker = Mouse::TypeRegistry->optimized_constraints->{$type};
+ return $checker if $checker;
+
+ confess "Unable to parse type constraint '$type'";
+}
+
+sub verify_type_constraint {
+ my $self = shift;
+ local $_ = shift;
+
+ my $type = $self->type_constraint
+ or return 1;
+ my $constraint = $self->find_type_constraint
+ or return 1;
+
+ return 1 if $constraint->($_);
+
+ my $name = $self->name;
+ Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $_");
+}
+
1;
__END__