Not knowing the package means information must be returned by the loading mechanism, so that means we need to use do
.
Using do
means we can't use the symbol table, which means anonymous subs.
Create a file that looks like the following:
sub foo { ... }
sub bar { ... }
{
foo => \&foo,
bar => \&bar,
};
or like
{
foo => sub { ... },
bar => sub { ... },
};
Then use
my $table = do '/abs/path/to/file.pl' or die $@;
$table{foo}->();
or
my $table = do 'rel/path/to/file.pl' or die $@; # Relative to entries in @INC
$table{foo}->();
You can call do
more than once, but avoid it, as it compiles and runs the file every time. Cache the value it returns instead.
UGLY! And all because you don't want any relation between the file name and the package therein. If you go about trying to circumvent Perl's requirements, expect ugliness. It doesn't even help you any to have this requirement, so get rid of it.
What should do instead is create a file that looks like the following:
package Some::Package;
sub foo { shift; ... }
sub bar { shift; ... }
1;
The calling code would be:
my $file= 'Some/Package.pm';
my $pkg = $file;
$file =~ s{\.pm\z}{};
$file =~ s{/}{::}g;
require $file;
$pkg->foo();
See also Module::PluginFinder.