diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1998-06-18 16:26:59 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1998-06-18 16:26:59 +0000 |
commit | adaafad26d5bef10acc55989794c3767dc3c9dec (patch) | |
tree | 13b744ca45277cb3cbfadda49c470e934681a8bc /lib/AutoLoader.pm | |
parent | 474d7bc50a9e23e993d679b3e6b49bf8317f59cb (diff) | |
download | perl-adaafad26d5bef10acc55989794c3767dc3c9dec.tar.gz |
fix AutoLoader to do the right thing when there are relative paths
in @INC
p4raw-id: //depot/perl@1141
Diffstat (limited to 'lib/AutoLoader.pm')
-rw-r--r-- | lib/AutoLoader.pm | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/lib/AutoLoader.pm b/lib/AutoLoader.pm index 46e0a4be7a..666c6cacf9 100644 --- a/lib/AutoLoader.pm +++ b/lib/AutoLoader.pm @@ -2,31 +2,73 @@ package AutoLoader; use vars qw(@EXPORT @EXPORT_OK); +my $is_dosish; +my $is_vms; + BEGIN { require Exporter; @EXPORT = (); @EXPORT_OK = qw(AUTOLOAD); + $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32'; + $is_vms = $^O eq 'VMS'; } AUTOLOAD { my $name; # Braces used to preserve $1 et al. { - my ($pkg,$func) = $AUTOLOAD =~ /(.*)::([^:]+)$/; - $pkg =~ s#::#/#g; - if (defined($name=$INC{"$pkg.pm"})) - { - $name =~ s#^(.*)$pkg\.pm$#$1auto/$pkg/$func.al#; - $name = undef unless (-r $name); - } - unless (defined $name) - { - $name = "auto/$AUTOLOAD.al"; - $name =~ s#::#/#g; - } + # Try to find the autoloaded file from the package-qualified + # name of the sub. e.g., if the sub needed is + # Getopt::Long::GetOptions(), then $INC{Getopt/Long.pm} is + # something like '/usr/lib/perl5/Getopt/Long.pm', and the + # autoload file is '/usr/lib/perl5/auto/Getopt/Long/GetOptions.al'. + # + # However, if @INC is a relative path, this might not work. If, + # for example, @INC = ('lib'), then $INC{Getopt/Long.pm} is + # 'lib/Getopt/Long.pm', and we want to require + # 'auto/Getopt/Long/GetOptions.al' (without the leading 'lib'). + # In this case, we simple prepend the 'auto/' and let the + # C<require> take care of the searching for us. + + my ($pkg,$func) = $AUTOLOAD =~ /(.*)::([^:]+)$/; + $pkg =~ s#::#/#g; + if (defined($name=$INC{"$pkg.pm"})) { + $name =~ s#^(.*)$pkg\.pm$#$1auto/$pkg/$func.al#; + + # if the file exists, then make sure that it is a + # a fully anchored path (i.e either '/usr/lib/auto/foo/bar.al', + # or './lib/auto/foo/bar.al'. This avoids C<require> searching + # (and failing) to find the 'lib/auto/foo/bar.al' because it + # looked for 'lib/lib/auto/foo/bar.al', given @INC = ('lib'). + + if (-r $name) { + unless ($name =~ m|^/|) { + if ($is_dosish) { + unless ($name =~ m{^([a-z]:)?[\\/]}i) { + $name = "./$name"; + } + } + elsif ($is_vms) { + # XXX todo by VMSmiths + $name = "./$name"; + } + else { + $name = "./$name"; + } + } + } + else { + $name = undef; + } + } + unless (defined $name) { + # let C<require> do the searching + $name = "auto/$AUTOLOAD.al"; + $name =~ s#::#/#g; + } } my $save = $@; - eval {local $SIG{__DIE__};require $name}; + eval { local $SIG{__DIE__}; require $name }; if ($@) { if (substr($AUTOLOAD,-9) eq '::DESTROY') { *$AUTOLOAD = sub {}; @@ -242,6 +284,10 @@ to a subroutine may have a shorter name that the routine itself. This can lead to conflicting file names. The I<AutoSplit> package warns of these potential conflicts when used to split a module. +AutoLoader may fail to find the autosplit files (or even find the wrong +ones) in cases where C<@INC> contains relative paths, B<and> the program +does C<chdir>. + =head1 SEE ALSO L<SelfLoader> - an autoloader that doesn't use external files. |