NAME
Role::Declare - declarative parameter and return type checking
SYNOPSIS
In the interface Role:
package My::Class::interface;
use Role::Declare;
use Types::Standard qw/:all/;
class_method create_object ( Str $name, Int $age ) : Return( InstanceOf['My::Class'] ) {
die "Age cannot be negative: $age" if $age < 0;
};
In the interface implementation:
package My::Class;
use Role::Declare::StrictWith;
with_strict 'My::Class::interface';
sub create_object { ... }
or:
package My::Class;
use Role::Tiny::With;
with 'My::Class::interface';
sub create_object { ... }
DESCRIPTION
Perl doesn't provide a way to describe an interface, much less validate its implementation. This module aims to fill that gap by providing an easy way to build a validation layer with subroutine attributes and Function::Parameters syntax.
How it works
Any package which uses Role::Declare becomes a role and receives a few keywords and attributes that generate method modifiers. This means any class which composes it will need to implement the listed methods (this will be enforced on composition). Method implementations will be affected by Class::MethodModifiers modifiers, which provide argument and return value type checking, as well as arbitrary assertions defined in the interface.
Having that validation layer on at all times introduces a performance penalty. It makes sense to keep it on during development and testing to catch bugs and remove it in production. Role::Declare::StrictWith provides a specialized version of Role::Tiny's with
function, which works only in test environments as defined by Devel::StrictMode.
EXPORTS
The following are exported into the callers namespace:
method
method $method ( $Type $foo, $Type $bar ) { ... }
A method declaration following the syntax of Function::Parameters - a list of parameters that can have type constraints, like those from Type::Tiny. $self
will be automatically provided.
The body can contain any checks that need to be done on the arguments before the method is executed, it will not overwrite the method itself.
class_method
class_method $method ( $Type $foo, $Type $bar ) { ... }
Like method, but instead of $self
generates a $class
variable, which must be of the type ClassName
, from Types::Standard.
instance_method
instance_method $method ( $Type $foo, $Type $bar ) { ... }
Like method, but requries $self
to be an Object
from Types::Standard.
:Return
This attribute can be used along with method, instance_method or class_method to add return value validation in scalar context (see :ReturnList for list context). It takes a single Type::Tiny constraint as an argument.
class_method $method ( $Type $foo, $Type $bar ) : Return( $Type ) { ... }
:ReturnMaybe
Same as :Return but allows undef
.
:ReturnList
Similar to :Return but gets triggered by list context returns. It's arguments are the same as for ArrayRef constraint from Type::Tiny.
class_method $method ( $Type $foo, $Type $bar ) : ReturnList( $Type ) { ... }
:ReturnMaybeList
Same as :ReturnList but will always allow an empty list.
:ReturnSelf
Require the method to return its invocant.
:ReturnMaybeSelf
Same as :ReturnSelf but allow undef
.
:ReturnObject
Shorthand for :Return(Object)
.
:ReturnMaybeObject
Same as :ReturnObject but allows undef
.
:ReturnInstanceOf
Require the method to return an instance of the specified class. :ReturnInstanceOf($class)
is equivalent to :Return(InstanceOf[$class])
.
:ReturnMaybeInstanceOf
Same as :ReturnInstanceOf but allows undef
.
DIAGNOSTICS
A [list|scalar] hook for $method already exists
For each method at most two return validations can be set up - one for list and one for scalar context. This means, you can specify both :Return(...)
and :ReturnList(...)
for a method but you can't use :ReturnMaybeList
and :ReturnList
at the same time.
Only a single constraint is supported
A :Return
attribute should have a single argument - a Types::Standard constraint. If you want to test a method for multiple different types, see Type::Tiny::Union.
List constraint not defined
A :ReturnList
or :ReturnMaybeList
was used without arguments, see ArrayRef
in Types::Standard for supported arguments.
AUTHOR
Szymon Nieznański <snieznanski@perceptyx.com>
LICENSE
'Role::Declare' is Copyright (C) 2020, Perceptyx Inc
This library is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.
This package is distributed in the hope that it will be useful, but it is provided "as is" and without any express or implied warranties.
For details, see the full text of the license in the file LICENSE.