Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

How Are Attributes Useful?

by Limbic~Region (Chancellor)
on Jan 18, 2005 at 21:24 UTC ( [id://423188]=perlquestion: print w/replies, xml ) Need Help??

Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:

All,
I have read perldoc perlsub and perldoc attributes and I just don't get it. In my opinion, the examples leave a lot to be desired such as how and why one my want to use attributes.

I am aware of the warning in the documentation indicating attribute declaration for variables is still evolving, so I will stick to subroutines for the purpose of this question. As far as I can tell, an attribute is nothing more than a label you can give to a subroutine that you can later query. I don't see much usefulness in this. I would have thought that it would somehow effect the way a subroutine behaved when it was invoked like the built-in attributes :lvalue and :locked.

There is a current conversation in the CB on this topic right now, but it seemed to me like a perfect opportunity to make a post so everyone could benefit from it. It is nice that you can label subs to make certain specific tasks easier but I was hoping there was a more general use that was more powerful.

Cheers - L~R

Replies are listed 'Best First'.
Re: How Are Attributes Useful?
by chromatic (Archbishop) on Jan 18, 2005 at 22:36 UTC

    I've used attributes productively a few times.

    In a client server application, I used attributes on methods of the model classes to implement access controls. The syntax was something like :Access( rw ) to mark a method as needing read and write access. The actual server class performed authorization and authentication and knew the permissions of remote users. Before delegating any method call to a model object, it would check the permissions.

    I could have done this without attributes, but it seemed like a nice way to keep the metadata (what does this method accomplish) in the same place as the actual code of the method.

    In a recent journal entry (Dark, Dark Corners of Perl), I speculated that it's possible to use attributes on methods to simplify declaring and accessing parameters. I'm not ready to demonstrate my proof of concept yet, but I really like how the syntax works. It's nice to be able to manipulate subroutines at the appropriate time without resorting to source filters.

      chromatic wrote:

      In a recent journal entry (Dark, Dark Corners of Perl), I speculated that it's possible to use attributes on methods to simplify declaring and accessing parameters. I'm not ready to demonstrate my proof of concept yet, but I really like how the syntax works. It's nice to be able to manipulate subroutines at the appropriate time without resorting to source filters.

      I wholeheartedly agree, and between the two, I would use your solution over mine any day of the week if it's feasible, but I have a couple of questions. First, can you do multi-method dispatch with that? I've been porting some Java to Perl and lack of MMD has been a pernicious source of bugs.

      Second, will this run under mod_perl? It's my understand that attributes rely on a CHECK block. That won't get triggered under mod_perl. I know we discussed this the other day, but for the life of me, I can't recall what was said :)

      Cheers,
      Ovid

      New address of my CGI Course.

        I think it'd be very easy to do MMD with this technique. There's one potentially tricky spot, but I think it's doable.

        I also think attributes will run just fine under mod_perl. Maypole uses them, for example, and it works. There are different ways to declare where Attribute::Handlers runs, for example.

        I don't use attributes, so I can't vouch for it either way, but if they don't work under mod_perl, someone should tell the Maypole developers that. It uses sub attributes for security purposes.
Re: How Are Attributes Useful?
by talexb (Chancellor) on Jan 18, 2005 at 21:55 UTC

    I'm not an expert, but I can bring some of my C experience to bear.

    The C language is bound closely to assembler, and as such has certain keywords that act like the attributes that you're talking about. One that comes to mind is volatile, a variable declaration modifier that signals the compiler that whenever that variable was used in an expression, its value had to be read from the memory location assigned to it -- because its value was volatile.

    Another example is the lock attribute discussed in the Camel (pp. 457-458); it gives the compiler a hint that only the thread that has locked a function is allowed to call it. This is an attempt to prevent a race condition.

    Finally, there's the oxymoron of the constant variable -- that's just a convenience that allows a constant value to be stored in a read-only variable. Any attempt to update this variable's value will be ignored.

    So to answer your question -- attributes are used to give hints to the compiler and the run-time about special treatment to be given to certain variables and functions. And sometimes that behaviour isn't fully defined -- it's to leave future perl developers (note the lower case 'p') room to expand, as necessary.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      "shared" variables in threads::shared is a good real-world example of attribute use.

      And the now deprecated "locked" attribute works (worked) almost identically to how Java handles the synchronized keyword on methods...

      c.

      talexb,
      I don't mean offense, but this really doesn't help at all. The only example of attributes that I have seen that doing anything useful are the built-in ones that I mentioned in my question. You have described them without providing an example which is the same problem I had with the documentation. Can you give me an example of using attributes to make a read-only variable/sub? The question was looking for something tangible and to me this is just window dressing.

      Cheers - L~R

        Look at Attribute::Protected and Attribute::Property. More specifically, look at their source to see what they're doing. Essentially, both are inserting some extra code that runs (fairly transparently) in advance of the code block you provided with the subroutine definition.

        There are legitimate issues around when attributes get run (i.e. during the CHECK phase by default) and whether this is mod_perl safe, but this can be coded around as some others have mentioned. Personally, I think they're an interesting concept that hasn't matured properly yet. Essentially, it's an attempt at specifying behavior as a bunch of building blocks -- another way of templating functionality and reducing redundant code.

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: How Are Attributes Useful?
by Zaxo (Archbishop) on Jan 18, 2005 at 22:24 UTC

    I recall you have been studying the :lvalue attribute for subs. Reflect that that attribute is more than a tag that you may query at runtime like some kind of metadata. I'm not sure how I'd go about querying that.

    When the :lvalue attribute is applied to a sub, it changes how the sub is compiled and what usage is permitted of it.

    The description of attributes as tags to be queried sounds a lot like the "properties" Lisp can attach to a symbol. I think that's a mischaracterization.

    A read of the Attribute::Handlers pod suggests that magic outside runtime is what attributes are for. Those docs give some non-trivial examples. I suspect that perldoc -m Attribute::Handlers will yield lots of wisdom on the matter, but I know for a fact it won't be easy ;-)

    I'm sure that perl attributes would benefit from more of us experimenting with them.

    After Compline,
    Zaxo

      Zaxo,
      Reflect that that attribute is more than a tag that you may query at runtime like some kind of metadata. I'm not sure how I'd go about querying that.

      Really. I haven't found a single example of how one might modify the behavior of a subroutine using attributes outside the few built-ins. As far as querying the attributes - it was in the synopsis of perldoc attributes

      use attributes (); # optional, to get subroutine declarations my @attrlist = attributes::get(\&foo);
      I have looked at Attribute::Handlers and still felt unsatisfied. Attribute::Handlers::Prospective looks promising after glancing at the documentation but I find it hard to believe that there are no code examples outside the module. Why is this I wonder. It seems to me that you are right - the majority of us are in the dark and so attributes, if useful at all as others have implied, are way underdeveloped in perl.

      Cheers - L~R

        Check Bot-CPAN. It's Glue module uses Attribute::Handlers to define well.. attributes to methods. That lets you define a bot command like:

        sub list :help ("lists available modules") :private :adminCmd { # implements list() }

        I thought that was a rather elegant way of doing this.

      No, they are just text tags. Perl checks for the "lvalue" tag and, if found, does special processing. But the attribute is just a way to tell Perl to do that special processing.

      - tye        

        That's an implementation detail. The point is that thay represent metadata for the perl compiler, not the user's runtime. It's magic, I say!

        After Compline,
        Zaxo

Re: How Are Attributes Useful?
by Thilosophy (Curate) on Jan 19, 2005 at 02:25 UTC
    I am using subroutine attributes with CGI::App to automatically register run-modes (rather than having to set them up manually)
    package MyApp; use base 'CGI::Application'; use CGI::Application::Plugin::AutoRunmode qw [ cgiapp_prerun]; sub my_run_mode : Runmode { # do something here } sub another_run_mode : Runmode { # do something else } # you now have two run modes # "my_run_mode" and "another_run_mode"
    The module is still somewhat experimental, and hence not yet on CPAN, but if you want to give it a spin: perldoc download
Re: How Are Attributes Useful?
by CountZero (Bishop) on Jan 18, 2005 at 22:42 UTC
    IIRC, Maypole makes use of subroutine attributes to check whether some subroutines are "exported" or not. Rather than having to maintain a list of "exported" subroutines, you simply add the "exported" attribute to the subroutine and Maypole will do the right thing (or so the docs say -- unfortunately I have not been able to get Maypole running on my system).

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      CountZero,
      This was an example tye provided in the CB where the same thing could be accomplished without attributes. Like I said, it is nice that it makes certain very specific tasks easier but it seems that there should be something more general and more powerful about them. I haven't had a chance to go through all of the replies yet so hopefully someone has demystified it for me/us.

      Cheers - L~R

Re: How Are Attributes Useful?
by dimar (Curate) on Jan 18, 2005 at 23:41 UTC

    One thing that seems to be missing from the picture is why would the 'non-behavior-changing' aspect of attributes detract from their utility? (assuming this aspect is not in dispute).

    It seems pretty straightforward to envision a circumstance where someone might want to redefine metadata about a subroutine or method, without necessarily changing its name.

    If you will, please consider a simple illustration:

    If you are familiar with Windows, you notice how a filename allows essentially a 'basename' plus an 'extension' ... there have been numerous times when I wished I could sort or view files based on something besides just that. In other words, don't treat all these files exactly the same just because they all have the same extension 'txt' ... I want to segment them even further.

    The problem is the only workaround is to rename the files ... or append additional info to the filenames.

    ### before vacation_2003.txt vacation_2004.txt ### after vacation_2003.txt vacation_2004_hotels.ca.northern.txt vacation_2004_hotels.ca.southern.txt

    This is unacceptable if you have external dependencies that specifically rely on the previous filenames.

    The punchline is that naming files (and by analogy subroutines) is in large part an arbitrary choice, and entirely up to you. The only real constraint is that they be unique within the relevant scope. Therefore, talking about specific names people have used for their files in the past is never really going to illustrate the issue of *whether* a particular naming convention is useful for *you*.

    Thus, the (at least one) point of attributes is the ability to obviate the need for name changes as the exclusive method of distinguishing certain methods and properties into arbitrary subgroups (without breaking your code).

    No, this is not much more than adding little 'sticky notes' but still, that does not diminish their potential usefulness does it? This answers "how" they can be useful, but not "whether" they are useful in your specific project or circumstance, or according to your specific coding style.

      scooterm,
      to envision a circumstance where someone might want to redefine metadata about a subroutine or method, without necessarily changing its name

      It is my understanding that attributes are handled in the compiling phase (or rather non-runtime phases) so I fail to see how this would allow you to redefine the subroutine metadata. Could you provide an example of how to do this so that I might better understand?

      Cheers - L~R

        It is my understanding that attributes are handled in the compiling phase (or rather non-runtime phases)

        That is consistent with my understanding as well. I personally do not have sample code to honor your specific request, but it is a good question. Absent specific code samples, discusson on this topic tends to diminishing returns.

          It is my understanding that attributes are handled in the compiling phase (or rather non-runtime phases) ..

        Well, I disagree, but without either the knowledge of how perl works or the time to delve into the perl code, I can't back up my feeling about this. I think both compile-time *and* run-time behvaiour is affected by attributes.

        I wonder if TimToady or DanS could help us out here.

        Alex / talexb / Toronto

        "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re: How Are Attributes Useful?
by dragonchild (Archbishop) on Jan 19, 2005 at 15:05 UTC
    As far as I can tell, an attribute is nothing more than a label you can give to a subroutine that you can later query.

    That is exactly what a subroutine attribute is. Nothing more, nothing less. If you want special behavior associated with a given label, you have to add it yourself. (:lvalue and friends have that behavior associated by Perl itself.)

    I don't see much usefulness in this.

    There have been several examples above for the usefulness. Basically, I think of it as meta-programming. Sometimes, you want to say that these three classes implement this interface. Sometimes, you want to say that this variable is of this class. Sometimes, you want to say that these two subroutines are special in some way.

    For example, attributes are definitely useful for CGI::Application, which is why Thilosophy is working on auto-declaring runmodes. Maypole is finding it useful for a similar reason.

    Me, I tend to write engines. For example, PDF::Template has a basic engine - each node in the parsetree can potentially execute something at the following stages:

    • begin_page
    • enter_scope
    • render
    • deltas
    • exit_scope
    • end_page

    Ideally, I'd like to be able to mark a given method as executing during a given stage vs. having to declare a method of a given name and having to remember to call SUPER. This way, I can potentially declare more than one method as executing during a given stage. That allows me to write clearer code, instead of catch-all subroutines.

    (I can't do this, FYI, because PDF::Template has to be usable under mod_perl.)

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: How Are Attributes Useful?
by metaperl (Curate) on Jan 19, 2005 at 01:08 UTC
    apparently, they save you from creating a bunch of pointers to the subs that you want for a certain thing. Test::Class, for instance, allows you to attribute subs so that each set of subs performs certain roles in the testing process.
Re: How Are Attributes Useful?
by eric256 (Parson) on Mar 23, 2007 at 21:36 UTC

    I didn't realize till after compiling an example that this was a rather old post, but I'll post it anyway. Here is an example of using attributes to added debug information to a sub (printing out its @_ before and after execution) as well as a way to wrap some errors/warnings around methods. Both of these use Hook::LexWrap to warp extra code around the function being attributed...attributized, attributated?</code>

    use strict; use warnings; { package tools; use Data::Dumper; use Hook::LexWrap; use Attribute::Handlers; sub UNIVERSAL::Debug :ATTR(CODE) { wrap $_[1], pre => sub { pop; print Dumper({'Pre' => \@_ + })}, post => sub { pop; print Dumper({'Post' => \@_ + })}, } sub UNIVERSAL::Method :ATTR(CODE) { my ($package, $symbol, $referent, $attr, $data, $phase) = +@_; wrap $_[1], pre => sub { my $self = shift; die "Must be used as a method" +unless ref($self) eq $package; }; } } { package Test; sub method_test :Method { print "This should be called on a reference\n"; } } package main; sub foo : Debug { print "This is the end!\n"; return 123;}; foo(1,2,3); my $x = bless {}, 'Test'; $x->method_test(); Test::method_test('hello'); __DATA__ $VAR1 = { 'Pre' => [ 1, 2, 3 ] }; This is the end! $VAR1 = { 'Post' => [ 1, 2, 3 ] }; This should be called on a reference Must be used as a method at attributes.pl line 16.


    ___________
    Eric Hodges
Re: How Are Attributes Useful?
by pemungkah (Priest) on Mar 24, 2007 at 08:40 UTC
    Take a look at Class::AutoPlug. It uses attributes to allow you to declaratively build pluggable versions of non-pluggable modules using attributes and some clever uses of import(). Essentially, your pluggable main class looks like
    package Something::Pluggable; use base qw(Class::Autoplug::Pluggable); 1;
    and your plugins look like
    package Something::Plugin::Foo; use base qw(Class::AutoPlug::Plugin); sub x:PluggedMethod(methodName) { ...} sub y:Prehook(someBaseMethod) { ... } sub z:Posthook(someBaseMethod) { ... } 1;
    All the monkey code to find the methods, add hooks, etc., is handled inside the base classes, letting you concentrate on the actual job at hand. Attributes make it easy to define what you want declaratively, without stuff like having to construct lists of methods and hooks.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 09:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found