Search code examples
perloopmoose

How can I access Moose attributes from class methods?


Consider the following code:

package Test1;
use Moose; 

has 'something' => (
    is => 'rw',
    default => 'BLAH!'
);

sub printSomething {
    my ($self) = @_;
    ## What should I use here to get the value of something?
    print $self->something;
}

package Test2;

Test1->printSomething();

How can printSomething access something?


Solution

  • It can't. You have to instantiate a Test1 object in order for attribute defaults to be constructed. They don't hang out in the class.

    If you want true class attributes in Moose, you can just write a method that closes over something and returns it:

    {
        my $class_attr = 'BLAH!';
        sub something { 
            return $class_attr;
        }
    }
    

    Of course, then you have to do some more work to add setters and clearers and whatnot, if you need those. A better way is to use MooseX::ClassAttribute like this:

    package Test1;
    
    use Moose;
    use MooseX::ClassAttribute;
    
    class_has 'something' => ( 
        is       => 'rw',
        default  => 'BLAH!'
    );
    

    That has the advantage of making Moose aware of your class attribute, and adding in meta-introspection goodness automatically.