http://qs321.pair.com?node_id=606087

rvosa has asked for the wisdom of the Perl Monks concerning the following question:

Dear monks,

I'm trying to understand how attributes work. I still don't get it. Why does the following not work (and is it fixable)?
package Attr; sub new :Constructor { return bless {}, shift } sub set_blah :Mutator { my ( $self, $blah ) = @_; $self->{blah} = $blah; return $self; } sub get_blah :Accessor { my $self = shift; return $self->{blah}; } 1; package main; my $obj = Attr->new; $obj->set_blah('I just set something!'); print $obj->get_blah;
All I get is Invalid CODE attribute: Constructor at /Users/rvosa/Desktop/Attr.pl line 3. So is it possible to set (arbitrary) attributes on methods, and how is that done?

Replies are listed 'Best First'.
Re: how to use attributes?
by blokhead (Monsignor) on Mar 22, 2007 at 18:48 UTC
    You can't declare subs (or variables) using attributes that have not been "defined" yet. To define your own attributes, you can use a module like Attribute::Handlers. For each attribute, you specify a handler that gets called whenever a sub (or variable) is defined using that attribute.

    blokhead

      Aha! That's what I needed, I think. Thanks!
Re: how to use attributes?
by Limbic~Region (Chancellor) on Mar 22, 2007 at 23:29 UTC
Re: how to use attributes?
by Anno (Deacon) on Mar 22, 2007 at 18:57 UTC
    You can set arbitrary attributes, but you must support them in your class. To get on track, add this early in your class definition:
    sub MODIFY_CODE_ATTRIBUTES { print "called with (@_)\n"; return }
    You can read more about it in attributes, section Package-specific Attribute Handling

    Anno

Re: how to use attributes?
by Moron (Curate) on Mar 22, 2007 at 18:41 UTC
    No, only the attributes listed in the documentation you reference are supported. E.g. "locked" is supported but "Constructor" isn't.

    Correction: "Arbitrary" attributes need a handling subroutine (of the same name as the attribute) to be defined in your class. That facility also needs to be turned on using Attribute::Handlers. Your code will then only work on v5.6.0 of Perl onwards and so should therefore formally require that version (or a later one if otherwise appropriate). For example:

    require v5.6.0; use Attribute::Handlers; package Whatever; #... sub Mutator : ATTR{CODE} { my ( $package, $symbol, $referent, $attr, $data ) = @_; # ... do whatever you want with mutators }
    User-defined attributes can apply to other types, not just CODE as also explained in the documentation.

    -M

    Free your mind

Re: how to use attributes?
by varian (Chaplain) on Mar 22, 2007 at 18:34 UTC
    ':Constructor' is not a valid Perl attribute,
    Just replace those attributes by the word ':method' and your code will run fine.
    package Attr; sub new :method { return bless {}, shift } sub set_blah :method { my ( $self, $blah ) = @_; $self->{blah} = $blah; return $self; } sub get_blah :method { my $self = shift; return $self->{blah}; } 1; package main; my $obj = Attr->new; $obj->set_blah('I just set something!'); print $obj->get_blah;
      Thanks for the reply, but I said arbitrary attributes. If I can only set the attribute "method", then that reminds me of Henry Ford saying you can have your Model T in any color you like, as long as that color is "black".
Re: how to use attributes?
by xdg (Monsignor) on Mar 23, 2007 at 13:47 UTC

    If the answers above still leave questions, I wrote up a somewhat detailed description of how attributes work in Re: Class::Std : How does MODIFY_HASH_ATTRIBUTES work?. It's really all just a chain of method calls triggered by the ":ATTR" syntax.

    -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 to use attributes?
by Zaxo (Archbishop) on Mar 23, 2007 at 21:53 UTC

    I played around with attributes some in my Dog $spot;. I haven't followed up on that, so what I know is reported there.

    After Compline,
    Zaxo