Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

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

by Arunbear (Prior)
on Jun 01, 2013 at 11:25 UTC ( #1036420=note: print w/replies, xml ) Need Help??

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

I wrote a module that used attributes to make sorted hashes. But to get syntax like
my %capital : Sorted;
the 'Sorted' sub (that provides the sorting behaviour) had to be pushed into the UNIVERSAL package, so if someone else wanted to provide a 'Sorted' attribute there would be a name collision.

The name collision could be avoided by using a non UNIVERSAL namespace, but then syntax like

my %capital : Hash::Sorted;
would be too cumbersome.

Replies are listed 'Best First'.
Re^2: RFC: Simulating Python's @decorators in Perl with Attributes (inheritance--)
by tye (Sage) on Jun 01, 2013 at 19:18 UTC

    Yes, Attribute::Handlers is really badly designed. It uses inheritance in stupid ways and requires things to be put into UNIVERSAL and other nonsense.

    I've implemented attributes by not using it and avoided these problems. I actually have a module that is an alternative to Attribute::Handlers that avoids these problems. It isn't on CPAN yet mostly because dealing with the possibility of somebody else having used Attribute::Handlers is a complex mess (and because this was a means to an end so my motivation was more about the module that used this than about this module).

    - tye        

      Your alternative to Attribute::Handlers sounds very useful. Perhaps the first release could just come with a warning that it may not play well with existing code that uses Attribute::Handlers (If I understood that part correctly)? Or maybe just 'release' it on Github?

        I was looking for something and not finding it and tripped over some stuff that reminded me that I might be nearby to this work so I found it. I was happy to find that I had already written a decent summary of the problems with Attribute::Handlers and even published that as part of something I put on CPAN: Devel::Init - Compatibility with Attribute::Handlers, etc. I'll copy it here for y'all's convenience:

        The design of encourages complex and hard-to-coordinate usage patterns that are (unfortunately) well demonstrated by Attribute::Handlers. Although early drafts of Devel::Init included complex code to try to support compatibility with Attribute::Handlers, it was determined that it is more appropriate for such compatibility to be handled in a more sane manner via changes to (or at least some other module).

        Devel::Init uses a much, much simpler approach for supporting attributes and also supports attributes::get() (which Attribute::Handlers appears to have completely ignored).

        Using use Devel::Init qw<:Init>; in package Some::Module (for example) is likely to cause uses of Attribute::Handlers or similar attribute-handling modules to be ignored (only for package Some::Module).

        This is because basically does Some::Module->can('MODIFY_CODE_ATTRIBUTES') and Devel::Init directly defines Some::Module::MODIFY_CODE_ATTRIBUTES() (and Some::Module::FETCH_CODE_ATTRIBUTES) while Attribute::Handlers makes complicated use of multiple layers of inheritance. Only one MODIFY_CODE_ATTRIBUTES() method is found and used by, and it will be the one defined by Devel::Init.

        Note that Attribute::Handlers does

        push @UNIVERSAL::ISA, 'Attribute::Handlers::UNIVERSAL'

        which means that every single class now magically inherits from Attribute::Handlers::UNIVERSAL. This is an extremely heavy-handed way to implement anything.

        Devel::Init will cooperate with an attribute-handling module that directly defines a Some::Module::MODIFY_CODE_ATTRIBUTES() method provided either that Devel::Init is loaded second or the other module also cooperates.

        Note that I added some clarifications (inside <ins> tags).

        It would have been much, much better if had made use of a global array of attribute handlers (per package) instead of single global attribute handling subroutines per package (and per operation type). Then a design as heavy-handed and misguided as Attribute::Handlers probably never would have been created. Especially bad was using ->can(), which just opens a big can of worms when trying to get multiple sources of attribute handlers to cooperate.

        You can see the mess needed to deal with the use of ->can() after the __END__ of But I realize that it doesn't even deal with the UNIVERSAL nonsense because 'UNIVERSAL' is just implicitly in @ISA.

        But these minor mis-steps by the author(s) of not only pale but blanch in comparison to the wildly inappropriate choices made by the author(s) of Attribute::Handlers.

        I lack the needed tolerances for trying to get improved. Simultaneously being ignored by the few, over-busy key people who need to accept what you have done mixes so irritatingly with not quite being able to ignore the functionaries on the list who don't seem to actually understand the work being done but have suggestions about how one could e-mail about the code one has written more effectively. Trying to submit a 3-line patch that fixes a fundamental bug in the basic working of hashes only takes about a decade when I try to do it via such means. Doing something actually difficult like transitioning to a different base methodology in and figuring out how much backward compatibility is enough would never actually succeed.

        But I do plan to upload an alternative to Attribute::Handlers.

        - tye        

Re^2: RFC: Simulating Python's @decorators in Perl with Attributes
by LanX (Bishop) on Jun 01, 2013 at 11:44 UTC
    > so if someone else wanted to provide a Sorted attribute there would be a name collision.

    In O'Reilly's Perl Hacks you'll find a similar issue with an attribute Doc for docstrings living in UNIVERSAL.

    Maybe we just need a module to safely add features to UNIVERSAL and warn about conflicts.

    > my %capital : Hash::Sorted;

    > would be too cumbersome.


    Maybe just leave it to the user. An import-option could specify the namespace.

    I wouldn't mind having different modules collecting their attributes into X:: like "eXtension".

    Why not X::Sorted or X::Doc ... or _::Sorted or _::Doc? :)

    BTW: Happy to find other's trying to use syntactic sugar to extend the language! =)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re^2: RFC: Simulating Python's @decorators in Perl with Attributes
by LanX (Bishop) on Jun 01, 2013 at 13:38 UTC
    > ...then syntax like
    my %capital : Hash::Sorted;

    > would be too cumbersome.

    did you ever get this to work? I can't.

    I even tried Perl4's quote as separator...

    use strict; use warnings; use Attribute::Handlers; package H; sub Sorted :ATTR { print "sorted" } package main; my $tst :H::Sorted; sub tst :H::Sorted { print "hui" } tst();
    Invalid separator character ':' in attribute list at /home/lanx/B/PL/P +M/ line 16, near "$tst :H" syntax error at /home/lanx/B/PL/PM/ line 16, near "$tst :H" Invalid separator character ':' in attribute list at /home/lanx/B/PL/P +M/ line 18, near "sub tst :H" syntax error at /home/lanx/B/PL/PM/ line 18, near "sub tst +:H" Execution of /home/lanx/B/PL/PM/ aborted due to compilation + errors.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      Sorry, the verbose syntax example I gave was wrong. It would actually be like this:
      #!/usr/bin/perl use strict; use warnings; package Foo::Sorted; use Attribute::Handlers; sub Sorted :ATTR { print "all sorted" } package main; my Foo::Sorted $tst :Sorted;
        But if you worry about name collision in UNIVERSAL (which isn't my biggest concern) why don't you just import the attribute Sorted into the current package?

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1036420]
and the leaves swirl about...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2018-06-22 03:50 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (121 votes). Check out past polls.