Mic
view release on metacpan or search on metacpan
lib/Mic/Assembler.pm view on Meta::CPAN
my $config_file = $ENV{MIC_CONTRACTS}
or return;
my $config = Config::Tiny->read($config_file);
Mic::ContractConfig::configure($config);
$self->{config_file_read} = 1;
}
sub _add_methods {
my ($spec, $stash) = @_;
my $in_interface = _interface($spec);
$spec->{implementation}{methods}{DOES} = sub {
my ($self, $r) = @_;
if ( ! $r ) {
my @items = (( $spec->{interface_name} ? $spec->{interface_name} : () ),
$spec->{name}, sort keys %{ $spec->{does} });
return unless defined wantarray;
return wantarray ? @items : \@items;
}
return $r eq $spec->{interface_name}
|| $spec->{name} eq $r
|| $spec->{does}{$r}
|| $self->isa($r);
};
$spec->{implementation}{methods}{can} = sub {
my ($self, $f) = @_;
if ( ! $f ) {
my @items = sort @{ $spec->{interface} };
return unless defined wantarray;
return wantarray ? @items : \@items;
}
return UNIVERSAL::can($self, $f);
};
while ( my ($name, $meta) = each %{ $spec->{implementation}{has} } ) {
_validate_slot_def($meta);
if ( ! $spec->{implementation}{methods}{ $meta->{reader} }
&& $meta->{reader}
&& $in_interface->{ $meta->{reader} } ) {
$spec->{implementation}{methods}{ $meta->{reader} } = sub {
my ($self) = @_;
return $self->[ $spec->{implementation}{slot_offset}{$name} ];
};
}
if ( ! $spec->{implementation}{methods}{ $meta->{property} }
&& $meta->{property}
&& $in_interface->{ $meta->{property} } ) {
confess "'property' can only be used from Perl 5.16 onwards"
if $] lt '5.016';
$spec->{implementation}{methods}{ $meta->{property} } = sub : lvalue {
my ($self) = @_;
return $self->[ $spec->{implementation}{slot_offset}{$name} ];
};
}
if ( ! $spec->{implementation}{methods}{ $meta->{writer} }
&& $meta->{writer}
&& $in_interface->{ $meta->{writer} } ) {
$spec->{implementation}{methods}{ $meta->{writer} } = sub {
my ($self, $new_val) = @_;
$self->[ $spec->{implementation}{slot_offset}{$name} ] = $new_val;
return $self;
};
}
_add_delegates($spec, $meta, $name);
}
while ( my ($name, $sub) = each %{ $spec->{implementation}{methods} } ) {
next unless $in_interface->{$name};
$stash->add_symbol("&$name", subname $stash->name."::$name" => $sub);
}
foreach my $name ( @{ $spec->{interface} } ) {
_add_pre_conditions($spec, $stash, $name, 'object');
_add_post_conditions($spec, $stash, $name, 'object');
_add_overloads($spec, $stash, $name, 'object');
}
_add_invariants($spec, $stash);
}
sub _validate_slot_def {
validate(@_, {
default => { type => SCALAR | CODEREF, optional => 1 },
handles => { type => ARRAYREF | HASHREF, optional => 1 },
init_arg => { type => SCALAR, optional => 1 },
property => { type => SCALAR, optional => 1 },
reader => { type => SCALAR, optional => 1 },
writer => { type => SCALAR, optional => 1 },
});
}
sub _add_invariants {
my ($spec, $stash) = @_;
return unless $Mic::Contracts_for{ $spec->{name} }{invariant};
my $inv_hash =
(! ref $spec->{interface}
&& $Mic::Spec_for{ $spec->{interface} }{interface_meta}{invariant})
|| $spec->{interface_meta}{invariant}
or return;
$spec->{invariant_guard} ||= sub {
# skip methods called by the invariant
return if (caller 1)[0] eq $spec->{name};
( run in 1.308 second using v1.01-cache-2.11-cpan-364913b4093 )