Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Re: RFC: Simulating Python's @decorators in Perl with Attributes

by pokki (Monk)
on May 28, 2013 at 19:14 UTC ( #1035689=note: print w/replies, xml ) Need Help??

in reply to RFC: Simulating Python's @decorators in Perl with Attributes

Without introducing sub attributes into the mix (I have nothing against attributes myself, but they're uncommon enough that non-Monks may trip on them), I find that Class::Method::Modifiers does a good enough job of providing the same functionality as decorators without extra syntax. Moo exposes C::M::M directly while Moose reimplements it (unless I'm mistaken?). (Edit: tobyink points out that I am in fact mistaken, Moose got there first.)

use strict; use warnings; use 5.010; use Test::More; use Class::Method::Modifiers; sub makebold { my ($orig, @args) = @_; return '<b>'.$orig->(@args).'</b>'; } sub hello { return "ohai"; } around 'hello' => \&makebold; is(hello(), '<b>ohai</b>'); done_testing;

Replies are listed 'Best First'.
Re^2: RFC: Simulating Python's @decorators in Perl with Attributes
by LanX (Bishop) on May 28, 2013 at 19:35 UTC
    I think the essential point about attributes is to DRY when marking subs and variables.

    so this code might be explicit but repeats the subname hello as a string.

    around 'hello' => \&makebold;

    Please note that attributes are not necessarily wrapping code.

    One use-case for instance could be to set a breakpoint for the debugger

    sub tst :break { ... }

    Another to restrict the type to variables

    my $y :Int;

    which might be very helpful when trying to translate Perl code to a typed language like C.

    All use cases could be achieved by adding tst or $y to a hash somewhere, but the possibility to do it right at the point of interest w/o name repetition can be very handy and avoids headaches when refactoring.

    Just imagine the overhead for a refactoring tool to find all hellos after sub hello was renamed.

    Cheers Rolf

    ( addicted to the Perl Programming Language)


    I'm no expert of Moose's compile phases, but a DRY notation of around using attributes would look like

    sub hello :around(makebold) { return "ohai"; }

      All those other uses for attributes are useful and interesting, but I thought we were talking about method decoration?

      Decorators as code rather than syntax also allow you to decorate someone else's methods, or to compose some advice into some class through roles, even at runtime. This is not possible with attributes.

        Could it be that you are confusing the meaning of "decorator"?

        The term "decorator" in the Python universe has not much to do with the "decorator pattern".

        see also SO:Whats the difference between Python decorators and Decorator Pattern?

        The initial motivation to look again into Perl attributes was a discussion about Python decorators.

        While Perl attributes are more powerful, they are also more difficult to handle.

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Re^2: RFC: Simulating Python's @decorators in Perl with Attributes
by tobyink (Abbot) on May 28, 2013 at 19:45 UTC

    "Moo exposes C::M::M directly while Moose reimplements it (unless I'm mistaken?)."

    You've got it the wrong way around: Class::Method::Modifiers is the re-implementation; Moose came before it.

    Class::Trigger and Aspect are a fairly similar idea, though different interfaces.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1035689]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2017-12-17 09:07 GMT
Find Nodes?
    Voting Booth?
    What programming language do you hate the most?

    Results (462 votes). Check out past polls.