no warnings 'redefine'; *Foo::real_new = \&Foo::new; *Foo::new = sub { if (caller() eq 'Bar') { print "Returning real Foo.\n"; return Foo->real_new; } print "Returning fake Foo.\n"; return FakeFoo->new; }; #### { package Foo; use Moose; around new => sub { my ($orig, $class, @args) = @_; if (caller() eq 'Bar') { print "Returning real Foo.\n"; return $class->$orig(@args); } print "Returning fake Foo.\n"; return FakeFoo->new(@args); }; }