# PODNAME: MooseX::Extended::Manual::Includes
# ABSTRACT: An overview of MooseX::Extended optional features

our $VERSION = '0.01';

__END__

=pod

=encoding UTF-8

=head1 NAME

MooseX::Extended::Manual::Includes - An overview of MooseX::Extended optional features

=head1 VERSION

version 0.30

=head1 C<includes>

Some experimental features are useful, but might not be quite what you want.

By default, L<MooseX::Extended> tries to be relatively conservative. However,
you might want to turn it up to 11. There are optional, B<EXPERIMENTAL>
features you can use for this. They're turned by the C<includes> flag.

=head2 C<method>

    package My::Names {
        use MooseX::Extended types => [qw(compile NonEmptyStr Str )],
          includes                 => ['method'];

        param _name => ( isa => NonEmptyStr, init_arg => 'name' );
        param title => ( isa => Str, required => 0, predicate => 1 );

        method name() {
            my $title = $self->title; # $self is injected for you
            my $name  = $self->_name;
            return $title ? "$title $name" : $name;
        }
    }

Adds a C<method> keyword and injects C<$self> into the method body. Requires
L<Function::Parameters>.

Note: this is equivalent to writing:

    use Function::Parameters 'method';

The other features of L<Function::Parameters> are not available.

This feature does not work with the optional C<multi> keyword. Thus,  if you
do this:

    use MooseX::Extended includes => [qw/multi method/];

You cannot do C<multi method>. You'll have to fall back to C<multi sub>.

=head2 C<multi>

    use MooseX::Extended includes => [qw/multi/];

    multi sub foo ($self, $x)      { ... }
    multi sub foo ($self, $x, $y ) { ... }

Allows you to redeclare a method (or subroutine) and the dispatch will use the number
of arguments to determine which subroutine to use. Note that "slurpy" arguments such as
arrays or hashes will take precedence over scalars:

    multi sub foo ($self, @x) { ... }
    multi sub foo ($self, $x) { ... } # will never be called

Thus, the following probably doesn't do what you want.

    package Foo {
        use MooseX::Extended includes => [qw/multi/];

        multi sub foo ($self, @bar) { return '@bar' }
        multi sub foo ($self, $bar) { return '$bar' }
    }

    say +Foo->new->foo(1);
    say +Foo->new->foo(1,2,3);

Both of the above will print the string C<@bar>. The second definition of
C<foo> is effectively lost.

Only available on Perl v5.26.0 or higher. Requires L<Syntax::Keyword::MultiSub>.

This feature does not work with the optional C<method> keyword. Thus,  if you
do this:

    use MooseX::Extended includes => [qw/multi method/];

You cannot do C<multi method>. You'll have to fall back to C<multi sub>.

=head2 C<async>

    package My::Thing {
        use MooseX::Extended
        types    => [qw/Str/],
        includes => ['async'];
        use IO::Async::Loop;

        field output => ( is => 'rw', isa => Str, default => '' );

        async sub doit ( $self, @list ) {
            my $loop = IO::Async::Loop->new;
            $self->output('> ');
            foreach my $item (@list) {
                await $loop->delay_future( after => 0.01 );
                $self->output( $self->output . "$item " );
            }
        }
    }

Allows you to write asynchronous code with C<async> and C<await>.

Only available on Perl v5.26.0 or higher. Requires L<Future::AsyncAwait>.

=head2 C<try>

    package My::Try {
        use MooseX::Extended includes => [qw/try/];

        sub reciprocal ( $self, $num ) {
            try {
                return 1 / $num;
            }
            catch {
                croak "Could not calculate reciprocal of $num: $@";
            }
        }
    }

Allows you to use try/catch blocks, via L<Syntax::Keyword::Try>.

Only available on Perl v5.24.0 or higher. Requires L<Syntax::Keyword::Try>.

=head1 AUTHOR

Curtis "Ovid" Poe <curtis.poe@gmail.com>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2022 by Curtis "Ovid" Poe.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
