Josh Arenberg
Josh Arenberg

Reputation: 10558

Failure Behavior of Moose Role Modifier Functions

Given the below code example, when running Main::main, if the eval block fails, I would assume that the 'after' block in the role would never run. However, I'm in the midst of debugging an intermittent and hard-to-pin-down error that would suggest this is not the case.

Could someone explain how the 'flattening' process works in this context, and if there are any conditions in which the eval would fail but the after block would run?

Thanks Josh

package MyRole;
use Moose::Role;

after 'main' => sub {
    #some code that depends on main executing
};

package Main;
use Moose;
with 'MyRole';

sub main {
    eval {
        #main work
    };
    if ($@) {
        die 'what happens now?';
    }
}

Upvotes: 1

Views: 80

Answers (2)

stevenl
stevenl

Reputation: 6798

  • MyRole::main() would normally execute after Main::main().

  • They are not exactly flattened into one method with one after the other in that what you return in Main::main() is still what gets returned and anything you return in MyRole::main() is ignored.

  • If 'main work' fails, MyRole::main() will not execute since you also die in the catch (if $@) block, which means that the flow of execution dies before it reaches MyRole::main().

Upvotes: 2

cjm
cjm

Reputation: 62109

If main dies, then the after modifier will not run. However, it is possible for an eval to fail but $@ to be false. It sounds like that must be what's happening here. If the eval fails, but $@ is false, your error handling code won't run and main won't throw an exception. Thus, the after main code will be run.

This is one of the things Try::Tiny protects you against.

Upvotes: 2

Related Questions