DEV Community

kobaken
kobaken

Posted on

Released types for subroutines

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(*) => *
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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

Discussion (0)