[perl #128769] Improve base.pm @INC '.' handling
authorFather Chrysostomos <[email protected]>
Sun, 31 Jul 2016 20:51:36 +0000 (13:51 -0700)
committerFather Chrysostomos <[email protected]>
Sun, 31 Jul 2016 20:53:05 +0000 (13:53 -0700)
• Localise @INC only if necessary.
• Don’t mention '.' in the @INC list in the error message, since it
  was not in the @INC that was searched (this is accomplished by local-
  ising @INC in the same scope as the error).
• If a file exists that would have been loaded had '.' not been
  ignored, mention it and suggest ‘use lib’.
• Use the same number of closing as opening parentheses in the
  error message.

MANIFEST
dist/base/lib/base.pm
dist/base/t/incdot.t [new file with mode: 0644]

index 81261e1..5ac7db8 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -3163,6 +3163,7 @@ dist/base/t/fields.t              See if fields work
 dist/base/t/fields-5_6_0.t     See if fields work
 dist/base/t/fields-5_8_0.t     See if fields work
 dist/base/t/fields-base.t      See if fields work
+dist/base/t/incdoc.t           Test how base.pm handles '.' in @INC
 dist/base/t/isa.t              See if base's behaviour doesn't change
 dist/base/t/lib/Broken.pm      Test module for base.pm
 dist/base/t/lib/Dummy.pm       Test module for base.pm
index cfe53ae..1093eb6 100644 (file)
@@ -97,9 +97,9 @@ sub import {
             {
                 local $SIG{__DIE__};
                 my $fn = _module_to_filename($base);
+                my $localinc = $INC[-1] eq '.';
+                local @INC = @INC[0..$#INC-1] if $localinc;
                 eval {
-                    local @INC = @INC;
-                    pop @INC if $INC[-1] eq '.';
                     require $fn
                 };
                 # Only ignore "Can't locate" errors from our eval require.
@@ -115,11 +115,19 @@ sub import {
                 unless (%{"$base\::"}) {
                     require Carp;
                     local $" = " ";
-                    Carp::croak(<<ERROR);
+                    my $e = <<ERROR;
 Base class package "$base" is empty.
     (Perhaps you need to 'use' the module which defines that package first,
     or make that module available in \@INC (\@INC contains: @INC).
 ERROR
+                    if ($localinc && -e $fn) {
+                        $e .= <<ERROS;
+    If you mean to load $fn from the current directory, you may
+    want to try "use lib '.'".
+ERROS
+                    }
+                    $e =~ s/\n\z/)\n/;
+                    Carp::croak($e);
                 }
                 $sigdie = $SIG{__DIE__} || undef;
             }
diff --git a/dist/base/t/incdot.t b/dist/base/t/incdot.t
new file mode 100644 (file)
index 0000000..fadebc4
--- /dev/null
@@ -0,0 +1,19 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+use base ();
+
+use Test::More tests => 2;
+
+if ($INC[-1] ne '.') { push @INC, '.' }
+
+my $inc = quotemeta "@INC[0..$#INC-1]";
+
+eval { 'base'->import("foo") };
+like $@, qr/\@INC contains: $inc\).\)/,
+    'Error does not list final dot in @INC (or mention use lib)';
+eval { 'base'->import('t::lib::Dummy') };
+like $@, qr<\@INC contains: $inc\).\n(?x:
+           )    If you mean to load t/lib/Dummy\.pm from the current >,
+    'special cur dir message for existing files in . that are ignored';