Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Sub attributes

by John M. Dlugosz (Monsignor)
on Jun 09, 2009 at 16:17 UTC ( [id://769987]=perlquestion: print w/replies, xml ) Need Help??

John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

The Catalyst framework uses attributes on subs. Looking this up in the Perl 5 documentation, I see the syntax and understand it OK. But I also see, "An attempt to set an unrecognized attribute is a fatal error." But nowhere does it explain how to declare an attribute so it becomes recognized. In particular, the examples use Bent without anything to make Bent "recognized". What's missing here?

Replies are listed 'Best First'.
Re: Sub attributes
by Limbic~Region (Chancellor) on Jun 09, 2009 at 17:59 UTC
    John M. Dlugosz,
    I posted How Are Attributes Useful? a long time ago. I wasn't the only one who felt a little underwhelmed by how useful user defined attributes were. I just want to point out that it is not clear in your question if you are asking about perl 5's sub attributes or Catalyst's use of them. If the latter, I would suggest #catalyst on irc.perl.org.

    Cheers - L~R

      I mean specifically the Perl 5 feature. The docs say it is an error to use one that is not recognized. So how do strings you want to use as attributes become "recognized"? If you can just use anything (warning if all lower case), the doc is wrong.
        John M. Dlugosz,
        I will quote the section germane to the conversation:

        An attempt to set an unrecognized attribute is a fatal error. (The error is trappable, but it still stops the compilation within that eval.) Setting an attribute with a name that's all lowercase letters that's not a built-in attribute (such as "foo") will result in a warning with -w ...

        I agree that the docs could use some explanation (echo'd by others in the thread I pointed to). On that front I can't offer you any insight other than to say that if you ignore the attributes pragma and use one of the modules, it does just seem to work. The only module I found useful (run arbitrary code at different phases) though (Attribute::Handlers::Prospective) used source filters.

        Cheers - L~R

Re: Sub attributes
by Your Mother (Archbishop) on Jun 09, 2009 at 16:53 UTC

    I can't point you to any documents or sample code right now but, in Cat at least, they are arbitrary strings which are parsed out. "Unrecognized" ones would only be fatal in this context if you intentionally made misparsing of them fatal. I have mixed feelings about them because it is just string wrangling here. They are very useful but seem clumsy (you can stack up a bunch of them for one controller sub) and I think it might be nice if the new Moose stuff would mutate them into some other syntax eventually.

      I think that MooseX::MethodAttributes might be what you are looking for. It is a nice meta-level API to sub attributes, and came out of the Catalyst Moosification I think.

      -stvn

        Thanks much. I only this weekend upgraded my main Cat stuff to 5.8 (on Moose). I was mildly amazed that nothing broke. I'm still a total Moose newbie but I really appreciate and admire the effort you and Dave and Sartak et al have put into it. I like seeing the frequent releases too.

Re: Sub attributes
by Bloodnok (Vicar) on Jun 09, 2009 at 18:27 UTC
    IIRC (I don't have the book to hand), Perl Hacks covers sub attributes...

    A user level that continues to overstate my experience :-))
      I checked it out...

      It's one page. Hack 45 (everything is called a "hack"), which shows that they exist and uses Attribute::Docstring and mentions Attribute::Handlers to make more things like that.

Re: Sub attributes
by lodin (Hermit) on Jun 10, 2009 at 11:23 UTC

    I'm not sure I understand the question. Maybe this code example is what you're looking for?

    use strict; use List::Extract 'extract'; sub MODIFY_CODE_ATTRIBUTES { my $class = shift; my ($cref, @attrs) = @_; my ($bent) = extract { /^Bent\b/ } @attrs; if (defined $bent) { print "Recognized attribute: $bent\n"; } return @attrs; # Unrecognized. } sub foo :Bent; sub bar :Bent(named) { 1 } my $code = sub :Bent(anonymous) { 1 } __END__ Recognized attribute: Bent Recognized attribute: Bent(named) Recognized attribute: Bent(anonymous)
    This is documented in attributes under "Package-specific Attribute Handling".

    What to do once a subroutine attribute is recognized is a completely different story. :-)

    lodin

      So only built-in attributes are recognized globally? That would contradict the examples. He's not setting up any package-attribute handler; just using Bent. And cautioning against unrecognized in nearly the same breath.

        So only built-in attributes are recognized globally?

        Correct. And that is how it should be. You don't want global attributes any more than you want global subroutines. I'm not saying that I like the current implementation, but at least its good that the attributes are somewhat scoped.

        Since the handlers (MODIFY_CODE_ATTRIBUTES etc) are inherited one can add them to UNIVERSAL and achieve global attributes. Attribute::Handlers for instance uses this trick. This however makes it very dangerous to use attributes in modules, since attributes defined in different modules may clash. See also my previous meditation on the problems with attributes (it also links to other nodes about attributes).

        lodin

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://769987]
Approved by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-26 03:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found