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

I have a few attributes in my class which are instances of other (heavy) classes. I don't want to incur a startup overhead of loading all these heavy classes unless the user accesses the attributes. To illustrate:

package MyClass; use Any::Moose; use Foo::Heavy; # slows startup! has foo => (is => 'ro', default => sub { Foo::Heavy->new });
I want the 'foo' attribute to behave something like this:
sub foo { my ($self) = @_; state $foo; if (!$foo) { require Foo::Heavy; $foo = Foo::Heavy->new; } $foo; }
Is there an easy way to do this in Moose?

Replies are listed 'Best First'.
Re: Moose/Mouse: assigning default to attribute on first access?
by bobr (Monk) on Jan 11, 2011 at 12:38 UTC
    You can set lazy on foo atribute and require in default. It will be called after foo is accessed.
    package MyClass; use Any::Moose; has foo => ( is => 'ro', lazy => 1, default => sub { require Foo::Heavy; Foo::Heavy->new; }, );

    -- regards, Roman

Re: Moose/Mouse: assigning default to attribute on first access?
by Anonymous Monk on Jan 11, 2011 at 12:31 UTC
    Set your attribute to lazy => 1. This is very useful when some attributes' builder functions rely on others' values.
      Perfect, I knew Moose is awesome like that.