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>