NAME

Role::MethodReturns - around Method Modifiers with Parameter & Return Type Check

SYNOPSIS

    package My::Class::interface;
    
    use Role::MethodReturns;
    use Types::Standard qw/:all/;
    
    around create_object => class_method ( Str $name, Int $age ) {
        returns( InstanceOf['My::Class'] ,
            $original->( $class => ( $name, $age )
        )
    };

In the Interface consuming Class:

    package My::Class;
    
    use Role::Tiny::With;
    
    with My::Class::interface unless $ENV{ROLE_METHOD_RETURN}
    
    sub create_object {
        ...
    }

DESCRIPTION

Some languages have beautiful ways to describe a 'interface', explicitly showing what methods are available, what arguments need to be passed in and what it will return.

Perl does not.

But we have CPAN... Role::MethodReturns will bring some of this, by providing a few 'imports'.

EXPORTS

The following are exported into the callers namespace:

around

This is the around method modifier, imported from Role::Tiny. Basically, the interface being described, is nothing else than a role.

parameters

    around $method => parameters ( $Type $foo, $Type $bar ) { ... }

After this keyword, it expects a list of parameters, that can have type constraints, like those from Type::Tiny. parameters is a specific import using Function::Parameters and shifts off $orig and $self.

So, inside the around method modifier CODEBLOCK, one can do:

    $orig->( $self => ( ... ) );

instance_method

    around $method => instance_method ( $Type $foo, $Type $bar ) { ... }

Like parameters, but instead of $self generates a $instance variable, which must be of the type Object, from Types::Standard.

And inside the CODEBLOCK:

    $original->( $instance => ( ... ) );

class_method

    around $method => class_method ( $Type $foo, $Type $bar ) { ... }

Like parameters, but instead of $self generates a $class variable, which must be of the type ClassName, from Types::Standard.

And inside the CODEBLOCK:

    $original->( $class => ( ... ) );

method_parameters

    around $method => method_parameters ( $Type $foo, $Type $bar ) { ... }

Like parameters, but instead of $self generates a $invocant variable, which must be of the type Invocant, from Type::Params. Which is the union of Object type and <Class> type. Incase it is not sure which is being used.

And inside the CODEBLOCK:

    $original->( $invocant => ( ... ) );

returns

    returns ( $Type , $return_value )

Checks that the $return_value is of type $Type and returns that value, or dies otherwise.

This is borrowed from assert_return, found in Type::Tiny and friends.

maybe_returns

    maybe_returns ( $Type , $return_value )

Just like returns, however will accept undef as well.

returns_self

    returns ( $self , $return_value )

Checks that the the $return_value, is the same as $self. That is just for convenience when your method allows chaining and returns the same object.

maybe_returns_self

    returns ( $self , $return_value )

Same as returns_self except that it allows for undef to be returned. This could be nice for interfaces that do not want to throw exceptions and use undef as a return value, to indicate that 'something' went wrong and therfore do not return $self.

Be warned, allowing undef to be returned, this will break the moment one will try to chain methods. This causes "Can't call method $foo on undef" errors. Which, of course, can be caught using try blocks.

AUTHOR

Theo van Hoesel <tvanhoesel@perceptyx.com>

COPYRIGHT AND LICENSE

'Role::MethodReturns' is Copyright (C) 2019, 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.