Abstract-Meta-Class

 view release on metacpan or  search on metacpan

lib/Abstract/Meta/Attribute/Method.pm  view on Meta::CPAN

        } else {
            $self->[$storage_key] = $value;
        }
        $self;
    }    
    :
    sub {
        my ($self, $value) = @_;
        if (! defined $value && defined $default) {
            if (ref($default) eq 'CODE') {
                $value = $default->($self, $attr);
            } else {
                $value = $default;
            }
        }

        $on_validate->($self, $attr, 'mutator', \$value) if $on_validate;
        if ($data_type_validation) {
            $value = index_association_data($value, $accessor, $index_by)
                if ($associated_class && $perl_type eq 'Hash');
            $attr->validate_data_type($self, $value, $accessor, $associated_class, $perl_type);
            if($required) {
                if ($perl_type eq 'Hash') {
                    confess "attribute $accessor is required"
                      unless scalar %$value;
                      
                } elsif ($perl_type eq 'Array') {
                    confess "attribute $accessor is required"
                      unless scalar @$value;
                }
            }
        } else {
            confess "attribute $accessor is required"
              if $required && ! defined $value;
        }

        
        $on_change->($self, $attr, 'mutator', \$value) or return $self
          if ($on_change && defined $value);
        

        if ($transistent) {
            set_attribute($self, $storage_key, $value);
        } else {
            $self->{$storage_key} = $value;
        }
        $self;
    };
}


=item index_association_data

=cut

sub index_association_data {
    my ($data, $attr_name, $index) = @_;
    return $data if ref($data) eq 'HASH';
    my %result;
    if($index && $$data[0]->can($index)) {
        %result = (map {($_->$index, $_)} @$data);
    } else {
        %result = (map {($_  . "", $_)} @$data);
    }
    \%result;
}


=item validate_data_type

=cut

sub validate_data_type {
    my ($attr, $self, $value, $accessor, $associated_class, $perl_type) = @_;
    my $array_storage_type = $attr->storage_type eq 'Array';
    if ($perl_type eq 'Array') {
        confess "$accessor must be $perl_type type"
            unless (ref($value) eq 'ARRAY');
        if ($associated_class) {
            validate_associated_class($attr, $self, $_)
              for @$value;
        }
    } elsif ($perl_type eq 'Hash') {
        confess "$accessor must be $perl_type type"
          unless (ref($value) eq 'HASH');
        if ($associated_class) {
            validate_associated_class($attr, $self, $_)
              for values %$value;
        }
    } elsif ($associated_class) {
        my $transistent = $attr->transistent;    
        my $storage_key = $attr->storage_key;
        my $current_value = $transistent ? get_attribute($self, $storage_key) : ($array_storage_type ? $self->[$storage_key] : $self->{$storage_key});
        return if ($value && $current_value && $value eq $current_value);
        $attr->deassociate($self);
        if (defined $value) {
            validate_associated_class($attr, $self, $value);
        }
    }
}


=item validate_associated_class

=cut

sub validate_associated_class {
    my ($attr, $self, $value) = @_;
    my $associated_class = $attr->associated_class;
    my $name = $attr->name;
    my $value_type = ref($value)
      or confess "$name must be of the $associated_class type";    
    return &associate_the_other_end if $value_type eq $associated_class;
    return &associate_the_other_end if $value->isa($associated_class);
    confess "$name must be of the $associated_class type, is $value_type";      
}


=item pending_transation

=cut

{   my %pending_association;



( run in 0.655 second using v1.01-cache-2.11-cpan-e93a5daba3e )