NAME
Types::Sub - type constraints for subroutines and Sub::Meta
SYNOPSIS
use Test2::V0;
use Types::Sub -types;
use Types::Standard -types;
my $Sub = Sub[
    args    => [Int, Int],
    returns => Int
];
use Function::Parameters;
use Function::Return;
fun add(Int $a, Int $b) :Return(Int) {
    return $a + $b
}
ok $Sub->check(\&add);
ok !$Sub->check(sub {});
done_testing;
DESCRIPTION
Types::Sub is type library for subroutines and Sub::Meta. This library can be used with Moo/Moose/Mouse, etc.
Types
Sub[`a]
A value where Ref['CODE'] and check by Sub::Meta#is_relaxed_same_interface.
use Types::Sub -types;
use Types::Standard -types;
use Sub::Meta;
use Function::Parameters;
use Function::Return;
fun distance(Num :$lat, Num :$lng) :Return(Num) { }
#
# Sub[`a] is ...
#
my $Sub = Sub[
    subname => 'distance',
    args    => { '$lat' => Num, '$lng' => Num },
    returns => Num
];
ok $Sub->check(\&distance);
#
# almost equivalent to the following
#
my $submeta = Sub::Meta->new(
    subname => 'distance',
    args    => { '$lat' => Num, '$lng' => Num },
    returns => Num
);
my $meta = Sub::Meta::CreatorFunction::find_submeta(\&distance);
ok $submeta->is_relaxed_same_interface($meta);
done_testing;
If no argument is given, it matches Ref['CODE']. Sub[] == Ref['CODE']. This helps to keep writing simple when choosing whether or not to use stricter type checking depending on the environment.
use Devel::StrictMode;
has callback => (
    is  => 'ro',
    isa => STRICT ? Sub[
        args    => [Int],
        returns => [Int],
    ] : Sub[]
);
StrictSub[`a]
A value where Ref['CODE'] and check by Sub::Meta#is_strict_same_interface.
SubMeta[`a]
A value where checking by Sub::Meta#is_relaxed_same_interface.
StrictSubMeta[`a]
A value where checking by Sub::Meta#is_strict_same_interface.
EXAMPLES
Function::Parameters
use Function::Parameters;
use Types::Standard -types;
use Types::Sub -types;
my $Sub = Sub[
    args => [Int, Int],
];
fun add(Int $a, Int $b) { return $a + $b }
fun double(Int $a) { return $a * 2 }
ok $Sub->check(\&add);
ok !$Sub->check(\&double);
Sub::WrapInType
use Sub::WrapInType;
use Types::Standard -types;
use Types::Sub -types;
my $Sub = Sub[
    args    => [Int, Int],
    returns => Int,
];
ok $Sub->check(wrap_sub([Int,Int] => Int, sub {}));
ok !$Sub->check(wrap_sub([Int] => Int, sub {}));
Sub::WrapInType::Attribute
use Sub::WrapInType::Attribute;
use Types::Standard -types;
use Types::Sub -types;
my $Sub = Sub[
    args    => [Int, Int],
    returns => Int,
];
sub add :WrapSub([Int,Int] => Int) {
    my ($a, $b) = @_;
    return $a + $b
}
sub double :WrapSub([Int] => Int) {
    my $a = shift;
    return $a * 2
}
ok $Sub->check(\&add);
ok !$Sub->check(\&double);
Sub::Meta::Library
use Sub::Meta::Library;
use Types::Standard -types;
use Types::Sub -types;
my $Sub = Sub[
    args    => [Int, Int],
    returns => Int,
];
sub add {}
my $meta = Sub::Meta->new(
    args    => [Int, Int],
    returns => Int,
);
Sub::Meta::Library->register(\&add, $meta);
ok $Sub->check(\&add);
SEE ALSO
LICENSE
Copyright (C) kfly8.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
AUTHOR
kfly8 <kfly@cpan.org>