I apologize, I have only just understood what you are doing. Pushing subroutine references onto @INC
is an arcane part of Perl functionality that few are aware of.
The documentation for require
says this:
You can also insert hooks into the import facility by putting Perl code directly into the @INC array. There are three forms of hooks: subroutine references, array references, and blessed objects.
Subroutine references are the simplest case. When the inclusion system walks through @INC and encounters a subroutine, this subroutine gets called with two parameters, the first a reference to itself, and the second the name of the file to be included (e.g., "Foo/Bar.pm"). The subroutine should return either nothing or else a list of up to three values in the following order:
1 - A filehandle, from which the file will be read.
2 - A reference to a subroutine. If there is no filehandle (previous item), then this subroutine is expected to generate one line of source code per call, writing the line into $_ and returning 1, then finally at end of file returning 0. If there is a filehandle, then the subroutine will be called to act as a simple source filter, with the line as read in $_ . Again, return 1 for each valid line, and 0 after all lines have been returned.
3 - Optional state for the subroutine. The state is passed in as $_[1] . A reference to the subroutine itself is passed in as $_[0].
The problem is that you are ignoring the parameters to the subroutines you are pushing onto @INC
. The second parameter will be the name of the module file that perl is trying to load, i.e. ReadElf.pm
, SimpleLogger.pm
or Table.pm
. Perl finds the first entry in @INC
that returns anything, and that is always the first subroutine, which fetches ReadElf.pm
and returns a file handle to read from it.
To load any one of these, as long as they are all in the same place in the Perforce repository, you can write
BEGIN {
push @INC, sub {
my ($self, $module) = @_;
my $file = "//sw/pvt/shashikanths/perl/mylib/$module";
open my $fh, "p4 print -q $file |";
return $fh;
}
}
This works by building the full path to the Perforce copy of the module and returning a file handle that will allow Perl to read it.
You really should check first that the file specified by $file
exists, and return nothing if not. Otherwise p4
is being run unnecessarily, and the subroutine returns a file handle regardless of whether the module was fetched successfully.