Applying Roles in Runtime from a Method Modifier

I have a role that provides a method modifier as follows:

package MyApp::Role::MenuExtensionRed;

use Moose::Role;
requires 'BuildMenu';

after 'BuildMenu' => sub {...};

Due to requirements elsewhere, I need to apply multiple roles at runtime, for example:

package MyApp::MainMenu

before 'BuildMenu' => sub {
    my ( $self, $args ) = @_;

    my $roles  = $args->{menu_extensions};
    apply_all_roles($self,@$roles);
};

sub BuildMenu {...}

However, the after modifier is never called. It’s clear that I am breaking some rules, but I would really like to understand why this does not work!

It works if, instead of applying roles to 'BuildMenu', I apply them in the BUILD method. But unfortunately, my menu_extension role list is not available at this point, so I have to wait.

Any alternative solutions would be appreciated!

EDIT , after 'BuildMenu' IS , BuildMenu. , . ? "" ?

+4
1

, .

, , .

,

before foo => sub {
}

:

my $orig = *package::foo;
*package::foo = sub {
     $beforetrigger->( @args );
     return $orig->( @args );
}

.

, , 2 subs, "A", BuildMenu, , "B", BuildMenu, .

, , :

First Call ->
   A ->  
    before ->
         apply roles ->
           replace A with B
    <-- return from before
    A body   ->
    <-- return from A Body
Subsequent Call 
   B -> something

Etc, , , , .

 around foo => sub { 
    my ( $orig, $self , @args ) = @_;
    # apply role to $self here
    # this gets the sub that will be resolved *after* the role is applied
    my $wrapped_sub = $self->can('foo');
    my $rval = $wrapped_sub->( $self, @args );      
    return $wrapped_sub->( $self, @args );
 }

, , $wrapped_sub - , , ,... , , , - .

, , , sub, sub, , , , , " " , =)

+2

All Articles