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


    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 {


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'.


The following are exported into the callers namespace:


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


    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 => ( ... ) );


    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 => ( ... ) );


    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 => ( ... ) );


    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 ( $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 ( $Type , $return_value )

Just like returns, however will accept undef as well.


    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.


    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.


Theo van Hoesel <>


'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.