It is useful to have a subroutine type, so I made one.
use Types::Sub -types;
use Types::Standard -types;
my $Sub = Sub[
args => [Int, Int],
returns => Int,
];
warn $Sub->validate(sub {})
# =>
# Reference sub { "DUMMY" } did not pass type constraint "Sub[sub(Int, Int) => Int]"
# Reason : invalid parameters: invalid args length. got: 0, expected: 2
# Expected : sub(Int, Int) => Int
# Got : sub(*) => *
If you can find the meta-information from the subroutine, the test will pass as follows.
use Types::Sub -types;
use Types::Standard -types;
my $Sub = Sub[
args => [Int, Int],
];
use Function::Parameters;
fun add(Int $a, Int $b) { return $a + $b }
ok $Sub->check(\&add);
use Sub::WrapInType qw(wrap_sub);
ok $Sub->check(wrap_sub([Int,Int] => Int, sub {}));
use Sub::WrapInType::Attribute;
sub add2 :WrapSub([Int,Int] => Int) {
my ($a, $b) = @_;
return $a + $b
}
ok $Sub->check(\&add2);
sub add3 {}
my $meta = Sub::Meta->new(
args => [Int, Int],
returns => Int,
);
Sub::Meta::Library->register(\&add3, $meta);
ok $Sub->check(\&add3);
Internally, Sub[...]
coerces subroutines into Sub::Meta and compares Sub::Meta against each other.
Give it a try!
https://metacpan.org/release/KFLY/Sub-Meta-0.14/view/lib/Types/Sub.pm
Top comments (0)