This is a complex question with regard to mro.pm , and the interplay with set_subname , and goto

In troubleshooting a problem, I think the core of my misunderstanding relates to how mro.pm works -- especially with regard to set_subname .

What is the difference between these three constructs,

Plain call to set_subname *Foo::bar = set_subname( 'Foo::bar', $codeRef ); Anon sub which wraps a set_subname *Foo::bar = sub { my $codeRef2 = set_subname('Foo::bar', $codeRef); goto $codeRef2 }; Anon sub which has its name set with set_subname *Foo::bar = set_subname( 'Foo::bar', sub { goto $codeRef } );

Specifically, the Mojo test suits fails with either of these modifications with anon subs applied to Mojo::Utils 's monkey_patch Running the two variants above against t/mojo/websocket_proxy.t ,

With the 2 (second) option I have *{"${class}::$k"} = sub { my $cr = set_subname("${class}::$k", $patch{$k}); goto $cr; }; And I get Mojo::Reactor::Poll: Timer failed: Can't locate object method "send" via package "Mojo::Transaction::HTTP" at t/mojo/websocket_proxy.t line 66.

With the 3 (third) option I have, *{"${class}::$k"} = set_subname("${class}::$k", sub { goto $patch{$k} }) And I get No next::method 'new' found for Mojolicious::Routes at /usr/lib/x86_64-linux-gnu/perl/5.28/mro.pm line 30.

Obviously, the first version works (it's from the code I linked), the question is why are the other two variants giving me different errors (especially the second variant) and what's happening there -- why don't they work?