Aion
view release on metacpan or search on metacpan
lib/Aion/Meta/Subroutine.pm view on Meta::CPAN
$args->validate(\@_, $args_of_meth);
wantarray? do {
my @returns = $referent->(@_);
$ret_array->validate(\@returns, $returns_of_meth);
@returns
}: do {
my $return = $referent->(@_);
$ret_scalar->validate($return, $return_of_meth);
$return
}
};
Sub::Util::set_prototype Sub::Util::prototype($referent), $sub;
Sub::Util::set_subname Sub::Util::subname($referent), $sub;
*{"$pkg\::$subname"} = $sub if $subname ne '__ANON__';
$self->{wrapsub} = $sub;
$Aion::META{$pkg}{subroutine}{$subname} = $self;
my $key = pack 'J', Scalar::Util::refaddr $sub;
$Aion::Isa{$key} = $self;
Scalar::Util::weaken $Aion::Isa{$key};
$self
}
sub compare {
my ($self, $subroutine) = @_;
die "Requires subroutine ${\$self->name}" unless $subroutine->isa('Aion::Meta::Subroutine');
my $i = 0;
my $signature = $subroutine->signature;
my $fail = 0;
if(@$signature == @{$self->signature}) {
for my $type (@{$self->{signature}}) {
my $other_type = $signature->[$i++];
$fail = 1, last unless $type eq $other_type;
}
} else {
$fail = 1;
}
die "Signature mismatch: ${\$self->stringify} <=> ${\$subroutine->stringify}" if $fail;
}
sub stringify {
my ($self) = @_;
my ($pkg, $subname) = @$self{qw/pkg subname/};
my $signature = join " => ", @{$self->signature};
return "$subname($signature) of $pkg";
}
1;
__END__
=encoding utf-8
=head1 NAME
Aion::Meta::Subroutine - describes a function with a signature
=head1 SYNOPSIS
use Aion::Types qw(Int);
use Aion::Meta::Subroutine;
my $subroutine = Aion::Meta::Subroutine->new(
pkg => 'My::Package',
subname => 'my_subroutine',
signature => [Int, Int],
referent => undef,
);
$subroutine->stringify # => my_subroutine(Int => Int) of My::Package
=head1 DESCRIPTION
Used to declare the required function in interfaces and abstract classes.
In this case, C<referent ~~ Undef>.
It also creates a wrapper function that checks the signature.
=head1 SUBROUTINES
=head2 new (%args)
Constructor.
=head2 wrap_sub ()
Creates a wrapper function that checks the signature.
=head2 compare ($subroutine)
Checks its (expected) signature against the one declared by the function in the module and throws an exception if the signatures do not match.
=head2 stringify ()
String description of the function.
=head2 pkg ()
Returns the name of the package in which the function is declared.
=head2 subname ()
Returns the name of the function.
=head2 signature ()
Returns the function signature.
=head2 referent ()
Returns a reference to the original function.
( run in 1.020 second using v1.01-cache-2.11-cpan-f56aa216473 )