my $trigger = $attribute->trigger;
my $type = $attribute->type_constraint;
my $constraint = $attribute->find_type_constraint;
+ my $builder = $attribute->builder;
my $accessor = 'sub {
my $self = shift;';
$accessor .= '}';
}
else {
+ $accessor .= 'confess "Cannot assign a value to a read-only accessor" if @_;';
}
if ($attribute->is_lazy) {
$accessor .= '$self->{$key} = ';
- $accessor .= ref($default) eq 'CODE'
- ? '$default->($self)'
- : '$default';
+
+ $accessor .= $attribute->has_builder
+ ? '$self->$builder'
+ : ref($default) eq 'CODE'
+ ? '$default->($self)'
+ : '$default';
+
$accessor .= ' if !exists($self->{$key});';
}
sub generate_handles {
my $attribute = shift;
my $reader = $attribute->name;
+ my %handles = $attribute->_canonicalize_handles($attribute->handles);
my %method_map;
- for my $local_method (keys %{ $attribute->handles }) {
- my $remote_method = $attribute->handles->{$local_method};
+ for my $local_method (keys %handles) {
+ my $remote_method = $handles{$local_method};
my $method = 'sub {
my $self = shift;
sub create {
my ($self, $class, $name, %args) = @_;
- confess "You must specify a default for lazy attribute '$name'"
- if $args{lazy} && !exists($args{default});
-
- confess "Trigger is not allowed on read-only attribute '$name'"
- if $args{trigger} && $args{is} ne 'rw';
+ confess "You cannot have lazy attribute ($name) without specifying a default value for it"
+ if $args{lazy} && !exists($args{default}) && !exists($args{builder});
confess "References are not allowed as default values, you must wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])"
if ref($args{default})
&& ref($args{default}) ne 'CODE';
- $args{handles} = { $self->_canonicalize_handles($args{handles}) }
- if $args{handles};
-
- $args{type_constraint} = delete $args{isa};
+ $args{type_constraint} = delete $args{isa}
+ if exists $args{isa};
my $attribute = $self->new(%args, name => $name, class => $class);
my $meta = $class->meta;
Creates a new code reference for each of the attribute's handles methods.
+=head2 find_type_constraint -> CODE
+
+Returns a code reference which can be used to check that a given value passes
+this attribute's type constraint;
+
+=head2 verify_type_constraint Item -> 1 | ERROR
+
+Checks that the given value passes this attribute's type constraint. Returns 1
+on success, otherwise C<confess>es.
+
=cut