A hack is required because require (and thus use ) both compiles and executes the module before returning.

Same goes for eval . eval can't be used to compile code without also executing it.

The least intrusive solution I've found would be to override DB::postponed . This is called before evaluating a compiled required file. Unfortunately, it's only called when debugging ( perl -d ).

Another solution would be to read the file, modify it and evaluate the modified file, kinda like the following does:

use File::Slurper qw( read_binary ); eval(read_binary("Foo.pm") . <<'__EOS__') or die $@; package Foo { no warnings qw( redefine ); sub bar { 7 } } __EOS__

The above doesn't properly set %INC , it messes up the file name used by warnings and such, it doesn't call DB::postponed , etc. The following is a more robust solution:

use IO::Unread qw( unread ); use Path::Class qw( dir ); BEGIN { my $preamble = ' UNITCHECK { no warnings qw( redefine ); *Foo::bar = sub { 7 }; } '; my @libs = @INC; unshift @INC, sub { my (undef, $fn) = @_; return undef if $_[1] ne 'Foo.pm'; for my $qfn (map dir($_)->file($fn), @libs) { open(my $fh, '<', $qfn) or do { next if $!{ENOENT}; die $!; }; unread $fh, "$preamble

#line 1 $qfn

"; return $fh; } return undef; }; } use Foo;

I used UNITCHECK (which is called after compilation but before execution) because I prepended the override (using unread ) rather than reading in the whole file in and appending the new definition. If you want to use that approach, you can get a file handle to return using

open(my $fh_for_perl, '<', \$modified_code); return $fh_for_perl;