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

I am attempting to use code attributes with Moo, however it seems that Moo doesnt load base/role classes early enough? And they attributes always seem to be invalid as MODIFY_CODE_ATTRIBUTES doesnt seem to be loaded.

For example

package Something::Base; use Scalar::Util qw( refaddr ); use Moo::Role; # _ATTRIBUTES stuff doesnt seem to be inherited early e +nough with Moo? ## use strict; use warnings; { my %attrs; sub MODIFY_CODE_ATTRIBUTES { my ($package, $subref, @attrs) = @_; $attrs{ refaddr $subref } = \@attrs; return; } sub FETCH_CODE_ATTRIBUTES { my ($package, $subref) = @_; my $attrs = $attrs{ refaddr $subref } or return; return @$attrs; } } package Something::Else; use Moo; with 'Something::Base'; #use base 'Something::Base'; # this works! sub foo : Foo(bar) { return 1 }

The above code will always give me 'Invalid CODE attribute' unless i 'use base/parent'. Neither extends nor with (roles) works. Wrapping the 'use Moo; with "Something::Base"' also works.

The Lexical::Attribute i can't get to work at all with inheritance. Either moo or use base/parent

Thoughts?

Replies are listed 'Best First'.
Re: Moo vs Code Attributes
by Loops (Curate) on Oct 27, 2014 at 12:29 UTC

    Is it safe to conclude that "with" is being processed after compilation of the source? Seems so, this works:

    BEGIN { with 'Something::Base'; }

      Yes, with and extends are just plain old exported subs; they don't execute at compile time unless you wrap them in BEGIN { ... }.

      An alternative is to define your attribute in UNIVERSAL, so you don't need to inherit or import it explicitly. Defining attributes in UNIVERSAL is quite commonly done, and not as awful as it sounds.