NAME

Mite::Manual::Keywords - functions exported by Mite

MANUAL

To start a class:

use Your::Project::Mite;

If you need to provide additional options:

use Your::Project::Mite qw( some options );

To start a role:

use Your::Project::Mite -role;

Or with additional options:

use Your::Project::Mite qw( -role some options );

Options which look like words are requesting the import of a keyword of that name. For example, this imports a keyword called lazy:

use Your::Project::Mite qw( lazy );

Options which start with an exclamation mark are the negation of that. For example to unrequest lazy:

use Your::Project::Mite qw( !lazy );

Options starting with a hyphen are either a bundle of keywords, or are a pragma which affect your class as a whole.

By default, classes get the has, extends, with, before, after, and around keywords imported into them.

By default, roles get has, requires, with, before, after, and around keywords imported into them.

The -all flag imports everything possible.

has $name => %spec

Like has in Moose, this declares one or more attributes. See Mite::Manual::Attributes for further details.

Mite supports the shortcut found in Mojo::Base and Object::Simple:

has $name => $default;

In these cases, if $default is a coderef, the attribute will use it as a builder and assume the attribute is => 'lazy', and otherwise will treat $default as a default and assume the attribute is => 'ro'.

If additional options are needed they can be provided, but by that point it's probably better to abandon the shortcut syntax.

has myattr => sub {
    return {};
}, is => 'rwp', isa => 'HashRef';

extends @parents

Declares the parent classes for your class.

You cannot use extends from within roles.

Like Moose, you can require a minimum version of a parent class:

extends(
    'Your::Project::SomeClass  => { -version => '1.000' },
    'Your::Project::OtherClass => { -version => '2.000' },
);

Multiple inheritance is supported if you're inheriting from Mite classes within your project. Single inheritance is supported if you're inheriting from a "foreign" class, as long as it uses a blessed hashref. (Multiple inheritance may in some cases work.)

requires @methods

Works as in Moose.

You cannot use requires from within classes.

with @roles

Works as in Moose.

Roles must be Mite roles created in your own project, or Role::Tiny roles. Mite does not support using roles from other projects, or using role implementations other than Mite and Role::Tiny.

Like Moose, you can require a minimum version of a role:

with(
    'Your::Project::SomeRole  => { -version => '1.000' },
    'Your::Project::OtherRole => { -version => '2.000' },
);

You can also alias and exclude methods (but not attributes) provided by roles:

with 'Your::Project::Mouth' => {
    -excludes => [ 'speak' ],
    -alias    => { 'belch' => 'burp' },
};

param and field

The param and field keywords are available, like MooseX::Extended. These act as an alternative to has.

use Your::Project::Mite qw( param field !has );

param foo => ( isa => 'Str' );

before, around, and after

Basic versions of the before, around, and after method modifiers are provided, but these may run in a different order from Moose if you use several modifiers on the same method.

signature_for $method_name => %spec

Installs a wrapper for a method enforcing a method signature, inspired by Type::Params. This is installed via the same mechanism as around, so is sensitive to the same concerns with regard to ordering, etc.

Simple example of named parameters:

signature_for my_method => (
    named => [
        foo  => 'Bool',
        bar  => 'Int', { default => 42 },
    ],
);

sub my_method {
    my ( $self, $arg ) = @_;
    
    if ( $arg->foo ) {
        return $arg->bar / 2;
    }
    else {
        return $arg->bar * 2;
    }
}

$object->my_method( foo => true, bar => 30 );
$object->my_method( { foo => true, bar => 36 } );
$object->my_method( foo => false );

Simple example using positional parameters:

signature_for my_method => (
    pos => [
        'Bool',
        'Int', { default => 42 },
    ],
);

sub my_method {
    my ( $self, $foo, $bar ) = @_;
    
    if ( $foo ) {
        return $bar / 2;
    }
    else {
        return $bar * 2;
    }
}

$object->my_method( true, 30 );
$object->my_method( false );

Simple example using named-to-list (named on the outside, positional on the inside):

signature_for my_method => (
    named => [
        foo => 'Bool',
        bar => 'Int', { default => 42 },
    ],
    named_to_list => true,
);

sub my_method {
    my ( $self, $foo, $bar ) = @_;
    
    if ( $foo ) {
        return $bar / 2;
    }
    else {
        return $bar * 2;
    }
}

$object->my_method( foo => true, bar => 30 );
$object->my_method( { foo => true, bar => 36 } );
$object->my_method( foo => false );

You can indicate that your sub is designed to be called as a function instead of a method (no $self):

signature_for my_func => (
    ...,
    method => false,
);

If you override a method with a signature in a parent class, then the parent's signature won't wrap the child's method, but you can inherit its signature:

signature_for '+my_func';

This will wrap your overridden method in the same signature as the parent method.

You can also modify the parent class signature in your child class to add extra named or positional parameters:

signature_for '+my_func' => (
    pos => [ Int ],
);

You cannot add parameters like this if the parent class's signature has a slurpy parameter. Nor can you add positional parameters if the parent class's signature has named parameters or vice versa. If you need to radically change the parent class's signature, it's best not to use the + sign, and instead define a whole new signature for the child class.

A role can define a signature and this signature will be applied to classes that consume the role:

package Your::Project::MessageTarget;
use Your::Project::Mite -role, -all;

signature_for send_message => (
    named => [
        subject => Str,
        body    => Str,
    ],
);

package Your::Project::Console;
use Your::Project::Mite -all;
with 'Your::Project::MessageTarget';

has handle => sub { \*STDOUT };

sub send_message {
    my ( $self, $arg ) = @_;
    print { $self->handle } $arg->subject, "\n";
    print { $self->handle } $arg->body, "\n\n";
    return;
}

Using + to extend signatures from roles is not currently supported.

true and false

Although they're not imported by default, you can import true and false keywords. They can made attribute definitions a little prettier:

use Your::Project::Mite qw( true false );
# OR:
use Your::Project::Mite qw( -bool );

has foo => (
    is => 'rw',
    required => true,
);

ro, rw, rwp, bare, and lazy.

You can export constants called ro, rw, rwp, bare, and lazy. Again, these can make attribute definitions prettier:

use Your::Project::Mite qw( ro rw -bool );
# OR:
use Your::Project::Mite qw( -is -bool );

has foo => ( is => rw, required => true );

carp, croak, and confess

These functions can be exported to your class:

use Your::Project::Mite qw( croak );

sub my_method {
    croak 'Not implemented yet';
}

The functions provided are superpowered versions of the ones from Carp. If called with multiple arguments, the first is treated as a format string for sprintf and the remainder are passed through Data::Dumper if they are references.

sub my_method {
    my $self = shift;
    croak '%s does not implement this method', ref( $self );
}

blessed

blessed from Scalar::Util can also be imported.

use Your::Project::Mite qw( blessed );

STRICT

A function similar to STRICT from Devel::StrictMode can be imported.

This allows you to do things like:

sub my_method {
    my $self = shift;
    croak "Should be called as an object method!"
        if STRICT && ! blessed( $self );
    
    ...;
}

The STRICT constant will be true if running under author testing, but usually false when running on end user's machines. This allows you to catch errors on your own machine but avoid slow error checking on the end user's machine.

guard

A function similar to guard from Scope::Guard can be imported.

use Your::Project::Mite qw( guard );

# Says "Hello world"
do {
    my $guard = guard { print "world\n" };
    print "Hello ";
};

BUGS

Please report any bugs to https://github.com/tobyink/p5-mite/issues.

AUTHOR

Michael G Schwern <mschwern@cpan.org>.

Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE

This software is copyright (c) 2011-2014 by Michael G Schwern.

This software is copyright (c) 2022 by Toby Inkster.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.