This example works fine:
use File::Slurp qw(read_file);
local *File::Slurp::read_file = sub {
return 'test';
};
warn File::Slurp::read_file('/root/test.txt'); # return 'test'
this one too:
use File::Slurp qw(read_file);
local *read_file = sub {
return 'test';
};
warn read_file('/root/test.txt'); # return 'test'
but if I use full name of function in typeglob it doesn't work and attempt to read file:
use File::Slurp qw(read_file);
local *File::Slurp::read_file = sub {
return 'test';
};
warn read_file('/root/test.txt');
Could anyone explain why I can not redefine subroutine by full namespace, File::Slurp::read_file
, and use by short name?
In case of object method, it works fine:
use LWP::UserAgent;
local *LWP::UserAgent::get = sub {
return HTTP::Response->new( undef, undef, undef, 'Hello world' );
};
my $ua = LWP::UserAgent->new;
warn $ua->get()->content;
Your problem is caused by how the way export works. and how Perl assigns names to values. In Perl each name is a link to a value so
sub read_line { ... }
creates an anonymous subroutine reference and assigns it to the name&read_line
In your first example you are overriding
File::Slurp::read_file
and then callingFile::Slurp::read_file
so you get your version ofFile::Slurp::read_file
.In your second example you are overriding your imported version of
read_file
and then calling that so you get your version ofread_file
In your third example the following happens:
use File::Slurp;
does a*read_file = \&File::Slurp::read_file
at compile time, which makesread_file
point to the existing version ofFile::Slurp::read_file
. Your code then assigns*File::Slurp::read_file
a new sub ref, however this does not changeread_file
and it still points to the sub ref thatFile::Slurp::read_file
originally pointed to. You then callread_file
which is pointing to the original imported version ofFile::Slurp::read_file
In your fourth example Perl's method resolution system means that you are calling
LWP::UserAgent::get
so this is equivalent to your first example.