The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

decorators - Apply decorators to your methods

VERSION

version 0.01

DESCRIPTION

Decorators are subroutines that are run at compile time to modify the behavior of a method. This can be something as drastic as replacing the method body, or something as unintrusive as simply tagging the method with metadata.

DECORATORS

A decorator is simply a callback which is associated with a given subroutine and fired during compile time.

How are decorators registered?

Decorators are registered via a mapping of decorator providers, which are just packages containing decorator subroutines, and the class in which you intend to apply the decorators.

This is done by passing in the provider package name when using the decorators package, like so:

    package My::Class;
    use decorators 'My::Provider';

This will make available, all the decorators in My::Provider for use inside My::Class.

How are decorators associated?

Decorators are associated to a subroutine using the "attribute" feature of Perl. When the "attribute" mechanism is triggered for a given method, we extract the name of the attribute and then attempt to find a decorator of that name in the associated providers.

This means that in the following code:

    package My::Class;
    use decorators 'My::Provider';

    sub foo : SomeTrait { ... }

We will encounter the foo method and see that it has the SomeTrait "attribute". We will then look to see if there is a SomeTrait decorator available in the My::Provider provider, and if found, will call that decorator.

How are decorators called?

The decorators are called immediately when the "attribute" mechanism is triggered. The decorator callbacks receieve at least two arguments, the first being a MOP::Class instance representing the subroutine's package, the next being the MOP::Method instance representing the subroutine itself, and then, if there are any arguments passed to the decorator, they are also passed along.

PERL VERSION COMPATIBILITY

For the moment I am going to require 5.14.4 because of the following quote by Zefram in the Sub::WhenBodied documentation:

  Prior to Perl 5.15.4, attribute handlers are executed before the body
  is attached, so see it in that intermediate state. (From Perl 5.15.4
  onwards, attribute handlers are executed after the body is attached.)
  It is otherwise unusual to see the subroutine in that intermediate
  state.

I am also using the ${^GLOBAL_PHASE} variable, which was introduced in 5.14.

It likely is possible using Devel::GlobalPhase and Sub::WhenBodied to actually implment this all for pre-5.14 perls, but for now I am not going to worry about that.

AUTHOR

Stevan Little <stevan@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2018 by Stevan Little.

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