NAME
    Role::Hooks - role callbacks

SYNOPSIS
      package Local::Role {
        use Moo::Role;
        use Role::Hooks;
    
        Role::Hooks->after_apply(__PACKAGE__, sub {
          my ($role, $target) = @_;
          print "$role has been applied to $target.\n";
        });
      }
  
      package Local::Class {
        use Moo;
        with "Local::Role";   # prints above message
      }

DESCRIPTION
    This module allows a role to run a callback when it is applied to a class
    or to another role.

  Compatibility
    It should work with Role::Tiny, Moo::Role, Moose::Role, Mouse::Role, and
    Role::Basic. Not all class builders work well with all role builders (for
    example, a Moose class consuming a Mouse role). But when they do work
    together, Role::Hooks should be able to run the callbacks. (The only
    combination I've tested is Moo with Moose though.)

    Some other role implementations (such as Moos::Role, exact::role, and
    OX::Role) are just wrappers around one of the supported role builders, so
    should mostly work.

    With Role::Basic, the `after_apply` hook is called a little earlier than
    would be ideal; after the role has been fully loaded and its methods have
    been copied into the target package, but before handling `requires`, and
    before patching the `DOES` method in the target package. If you are using
    Role::Basic, consider switching to Role::Tiny.

    Apart from Role::Tiny/Moo::Role, a hashref of additional arguments (things
    like "-excludes" and "-alias") can be passed when consuming a role.
    Although I discourage people from using these in general, if you need
    access to these arguments in the callback, you can check
    %Role::Hooks::ARGS.

    Roles generated via Package::Variant should work; see t/20packagevariant.t
    for a demonstration.

  Methods
    `before_apply`
          Role::Hooks->before_apply($rolename, $callback);

        Sets up a callback for a role that will be called before the role is
        applied to a target package. The callback will be passed two
        parameters: the role being applied and the target package.

        The role being applied may not be the same role as the role the
        callback was defined in!

          package Local::Role1 {
            use Moo::Role;
            use Role::Hooks;
            Role::Hooks->before_apply(__PACKAGE__, sub {
              my ($role, $target) = @_;
              print "$role has been applied to $target.\n";
            });
          }
  
          package Local::Role2 {
            use Moo::Role;
            with "Local::Role1";
          }
  
          package Local::Class1 {
            use Moo::Role;
            with "Local::Role2";
          }

        This will print:

          Local::Role1 has been applied to Local::Role2.
          Local::Role2 has been applied to Local::Class1.

        If you only care about direct applications of roles (i.e. the first
        one):

          Role::Hooks->before_apply(__PACKAGE__, sub {
            my ($role, $target) = @_;
            return if $role ne __PACKAGE__;
            print "$role has been applied to $target.\n";
          });

        If you only care about roles being applied to classes (i.e. the second
        one):

          Role::Hooks->before_apply(__PACKAGE__, sub {
            my ($role, $target) = @_;
            return if Role::Hooks->is_role($target);
            print "$role has been applied to $target.\n";
          });

    `after_apply`
          Role::Hooks->after_apply($rolename, $callback);

        The same as `before_apply`, but called later in the role application
        process.

        Note that when the callback is called, even though it's after the role
        has been applied to the target, it doesn't mean the target has
        finished being built. For example, there might be `has` statements
        after the `with` statement, and those will not have been evaluated
        yet.

        If you want to throw an error when someone applies your role to an
        inappropriate target, it is probably better to do that in
        `before_apply` if you can.

    `is_role`
        Will return true if the given package seems to be a role, false
        otherwise.

        (In fact, returns a string representing which role builder the role
        seems to be using -- "Role::Tiny", "Moose::Role", "Mouse::Role", or
        "Role::Basic"; roles built using Moo::Role are detected as
        "Role::Tiny".)

ENVIRONMENT
    The environment variable `PERL_ROLE_HOOKS_DEBUG` may be set to true to
    enable debugging messages.

BUGS
    Please report any bugs to
    <http://rt.cpan.org/Dist/Display.html?Queue=Role-Hooks>.

SEE ALSO
    Role::Tiny, Moose::Role.

AUTHOR
    Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE
    This software is copyright (c) 2020-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.

