=pod

=head1 NAME

Mite::Manual::Syntax - Moose-like syntax supported by Mite

=head1 MANUAL

L<Mite> is a subset of L<Moose>.  These docs will only describe what
Moose features are implemented or where they differ.  For everything
else, please read L<Moose> and L<Moose::Manual>.

=head2 C<< import >>

To start a class:

    use Your::Project::Mite;

To start a role:

    use Your::Project::Mite -role;

By default, classes get C<has>, C<extends>, C<with>, C<before>, C<after>,
and C<around> functions imported into them.

By default, roles get C<has>, C<requires>, C<with>, C<before>, C<after>,
and C<around> functions imported into them.

You can list additional functions you want to import:

    use Your::Project::Mite -role, qw( true false );

You can suppress importing default functions:

    use Your::Project::Mite -role, qw( !before !after !around );

=head2 C<< has $name => %spec >>

Like C<has> in Moose, this declares an attribute. Not all Moose options
are supported.

=over

=item C<is> B<< Enum["ro","rw","bare","rwp","lazy"] >>

Supported values for C<is> include "ro", "rw", and "bare" like Moose,
but also "rwp" and "lazy" like Moo. These are all just shortcuts for
defining other options.

The default is C<< is => 'bare' >>.

=item C<reader> B<< Maybe[Str] >> 

The name of the attribute reader method to generate. If set to "1",
will generate a reader called "get_foo" if your attribute is called
"foo" and "_get__foo" if your attribute is called "_foo".

If your attribute is defined as C<< is => "ro" >>, C<< is => "rwp" >>,
or C<< is => "lazy" >> then C<reader> defaults to C<< $name >>.

=item C<writer> B<< Maybe[Str] >> 

The name of the attribute writer method to generate. If set to "1",
will generate a writer called "set_foo" if your attribute is called
"foo" and "_set__foo" if your attribute is called "_foo". 

If your attribute is defined as C<< is => "rwp" >>, then C<writer>
defaults to C<< "_set_$name" >>.

=item C<accessor> B<< Maybe[Str] >>

The name of the dual-purpose attribute reader/writer method to generate.
If set to "1", will generate a reader called "foo" if your attribute is
called "foo" and "_foo" if your attribute is called "_foo". 

If your attribute is defined as C<< is => "rw" >>, then C<accessor>
defaults to C<< $name >>.

=item C<clearer> B<< Maybe[Str] >>

The name of the attribute clearer method to generate. If set to "1",
will generate a clearer called "clear_foo" if your attribute is called
"foo" and "_clear__foo" if your attribute is called "_foo".

=item C<predicate> B<< Maybe[Str] >>

The name of the attribute predicate method to generate. If set to "1",
will generate a predicate called "has_foo" if your attribute is called
"foo" and "_has__foo" if your attribute is called "_foo".

=item C<handles> B<< HashRef|ArrayRef >>

Delegated methods. Currying and native traits are not supported.

=item C<init_arg> B<< Maybe[Str] >>

The parameter expected to be passed to the constructor to initialize this
attribute. May be undef if the attribute should not be intitialized in the
constructor.

Defaults to the attribute's name.

=item C<required> B<Bool>

Indicates whether the attribute is required in the parameter. If the
attribute has a non-lazy default, this is ignored.

=item C<weak_ref> B<Bool>

Indicates that the attribute should weaken its reference to the
attribute value.

=item C<isa> B<< Str|TypeTiny >>

A string type name from L<Types::Standard>, L<Types::Common::String>,
or L<Types::Common::Numeric>, or a blessed L<Type::Tiny> object. If
using a blessed object, you'll be introducing a dependency for your
project on whatever type constraint library you're using, so prefer
string type contraint names.

Any string supported by L<Type::Utils> C<dwim_type> is supported, so
things like C<< "Int | Enum['small', 'medium', 'large']" >> should work!

If you need custom types, you can add something like this to your
F<.mite/config>:

    types: Your::Project::Types

The module C<Your::Project::Types> would be a type library constructed with
L<Type::Library>. It should just contain type constraints and coercions which
can be inlined, and none of your classes should load it directly (just rely
on Mite to load it). This way you can use custom types in your project and
your project will not have a dependency on Type::Library.

=item C<coerce> B<Bool>

Indicates that the attribute should attempt to coerce values to fit
the type constraint.

=item C<trigger> B<< CodeRef|Maybe[Str] >>

If set to a string, is the name of a method to call whenever a new
attribute value is set. This is I<not> called when an attribute is
defaulted. If set to "1", will assume a trigger called "_trigger_foo"
if your attribute is called "foo" and "_trigger__foo" if your
attribute is called "_foo".

If set to a coderef, acts like it was set to "1" but installs the
coderef into your class with that name.

=item C<default> B<< Undef|Str|CodeRef|ScalarRef >>

A default value for the attribute, or a coderef called as a method
to generate that default value.

Unlike Moose, you can alternatively include an inline string of Perl
code as a ScalarRef:

    has list => (
        is => 'ro',
        isa => 'ArrayRef',
        default => \ '[]',
    );

This has performance benefits over using a coderef as it avoids the
overhead of a sub call.

=item C<builder> B<< Str|CodeRef >>

If set to a string, is the name of a method to call to build the
default attribute value. If set to "1", will assume a builder called
"_build_foo" if your attribute is called "foo" and "_build__foo" if your
attribute is called "_foo".

If you used C<< is => "lazy" >>, this will default to "1".

If set to a coderef, acts like it was set to "1" but installs the
coderef into your class with that name.

=item C<lazy> B<Bool>

Indicates that the default should be set lazily. Defaults to false
unless you used C<< is => "lazy" >>.

=item C<alias> B<< Str|ArrayRef[Str] >>

A list of aliases for the attibutes. If the attribute has an init_arg
(including a default one), this provides alternative initialization
arguments. If the attribute C<< is => "rw" >>, then these aliases are
aliases for the accessor; otherwise they are aliases for the reader.

The strings can contain "%s" which will be replaced by the attribute
name, allowing this to work:

    has [ 'foo', 'bar' ] => (
        is => 'ro',
        alias => 'get_%s',
    );

If you try to create aliases but don't have a reader or accessor,
then as a last resort the alias will be an alias for the writer.

    # foo can be set using `set_foo` or `whatever`
    #
    has foo => (
        is => 'bare',
        writer => 1,
        alias => 'whatever',
    );

Aliases are not natively supported by Moose, but this feature is
analagous to L<MooseX::Aliases>.

=item C<documentation> B<Any>

This option is ignored, but you can set it to a documentation string
for your attribute.

    has name => (
        is => 'rwp',
        isa => 'Str',
        documentation => 'First name and surname',
    );

=back

Multiple attributes can be defined using an arrayref.

    # Defines get_foo, get_bar, set_foo, and set_bar.
    #
    has [ 'foo', 'bar' ] => (
        isa => 'Str',
        reader => 1,
        writer => 1,
    );

Like in Moose, you can use a plus sign to modify an attribute definition
from a role or parent class:

    has '+foo' => (
        default => sub { 'new default' },
    );

When modifying an attribute, you cannot use C<is>.

=head2 C<< extends @parents >>

Works as in L<Moose>.

You cannot use C<extends> from within roles.

Options hashrefs, including the C<< -version >> option are not implemented.

=head2 C<< requires @methods >>

Works as in L<Moose>.

You cannot use C<requires> from within classes.

=head2 C<< with @roles >>

Works as in L<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.

Options hashrefs, including the C<< -version >> option are not implemented.

=head2 C<strict>

Mite will turn strict on for you.

=head2 C<warnings>

Mite will turn warnings on for you.

=head2 C<BUILDARGS>

Works as in L<Moose>.

=head2 C<FOREIGNBUILDARGS>

Works as in L<Moo> and L<MooseX::NonMoose>.

=head2 C<BUILD> / C<BUILDALL>.

Works as in L<Moose>.

=head2 C<DEMOLISH>

Works as in L<Moose>.

On Perl older than 5.14, the C<< $in_global_destruction >> argument
will be undefined unless L<Devel::GlobalDestruction> is installed,
so add that to your project's dependencies if you are relying on it
and need to support older versions of Perl.

=head2 Strict Constructor

Mite provides a similar feature to L<MooseX::StrictConstructor>, so
your constructor will die if you pass it unknown attributes. 

=head2 Chainable Writers

Mite provides a similar feature to L<MooseX::Attribute::Chained>, so
writer methods, clearer methods, and accessor methods used as writers
all return C<< $self >>, so they can be chained:

  $object->clear_foo->set_bar( 42 )->set_baz( 99 );

=head2 Method Modifiers

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

=head2 Booleans

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

    use Your::Project::Mite qw( true false );
    # OR:
    use Your::Project::Mite qw( -bool );
    
    has foo => (
        is => 'rw',
        required => true,
    );

=head2 Constants for "is"

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

    use Your::Project::Mite qw( ro rw );
    # OR:
    use Your::Project::Mite qw( -is );
    
    has foo => ( is => rw, required => true );

=head2 C<param> and C<field> keywords

The C<param> and C<field> keywords are available, like L<MooseX::Extended>.

    use Your::Project::Mite qw( param field !has );
    
    param foo => ( isa => 'Str' );

=head1 BUGS

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

=head1 AUTHOR

Michael G Schwern E<lt>mschwern@cpan.orgE<gt>.

Toby Inkster E<lt>tobyink@cpan.orgE<gt>.

=head1 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.

=head1 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.

=cut
