Hi,

Roderich Schupp wrote:
> On Mon, Sep 1, 2008 at 12:21 AM, Ch Lamprecht <[EMAIL PROTECTED]> wrote:
> 
>> trying to pack an application that uses Storable with the --clean switch I
>> got stuck:
> 
> Forget about --clean, it's a red herring. FWIW I can reproduce your
> problem without --clean on Solaris.
> 
> It looks like some weird interaction between PAR and Autoloader.
> The reason for the error message seems to be that auto/Storable/_retrieve.al
> is loaded BEFORE auto/Storable/autosplit.ix (so that logcarp isn't known
> to be a sub). In fact, I get the same error message by doing
> 
> $  perl -cw .../auto/Storable/_retrieve.al

Thanks, Roderich, for the head start in tracking this down.

Well, yes, it is a strange interaction. Have a look at this code from
taken and simplified from AutoLoader::import, which tries to find&load
the autosplit.ix of a given module:

# Say $callpkg is "Storable".
(my $calldir = $callpkg) =~ s#::#/#g;
my $path = $INC{$calldir . '.pm'};
# Normally this $path is something like:
# ../i686-linux-thread-multi/Storable.pm
$path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#;
# now it's ../i686-linux-thread-multi/auto/Storable/autosplit.ix
eval { require $path; };
# This normally succeeds to load autosplit.ix!

There's backup logic, but that's never triggered normally and not with
pp --clean either!

In the pp --clean environment:

(my $calldir = $callpkg) =~ s#::#/#g;
my $path = $INC{$calldir . '.pm'};
# Since we're unpacking to a temporary directory
# under munged names, this is really:
# /tmp/par-smueller/temp-7388/uDcZi6glgw
$path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#;
# now it's STILL that funny path!
# That funny path is actually Storable.pm!
eval { require $path; };
# That eval just does a second "require 'Storable.pm'"!

What can be done to fix this?
a) Finally, somebody finds the time and stamina to remove the whole
name-munging thing from PAR. It drives every other user off the cliff.
b) Patch AutoLoader to work around this.

Now, I'll pursue b) just because a) simply takes more time and possibly
competence than I have. For starters, try applying the attached patch to
an installation of the current AutoLoader 5.66. It should make things
work by falling back to the relative path @INC search.

Arguably, this is a bug or at least a glitch in AutoLoader anyway: It
shouldn't eval the tentative autosplit.ix *unless* the path substitution
succeeded. If this fixes things for you, I can make an AutoLoader
developer release, then a normal one, then submit the patch to p5p.
(Read, this is going to take a while. Breaking AutoLoader by oversight
is bad, bad, bad.)

Best regards,
Steffen
--- /users/ik3al1/smueller/perl/lib/5.10.0/AutoLoader.pm	2008-09-01 12:14:59.000000000 +0200
+++ /tmp/AutoLoader.patched.pm	2008-09-01 12:16:27.000000000 +0200
@@ -15,7 +15,7 @@
     $is_epoc = $^O eq 'epoc';
     $is_vms = $^O eq 'VMS';
     $is_macos = $^O eq 'MacOS';
-    $VERSION = '5.66';
+    $VERSION = '5.67';
 }
 
 AUTOLOAD {
@@ -155,17 +155,20 @@
     (my $calldir = $callpkg) =~ s#::#/#g;
     my $path = $INC{$calldir . '.pm'};
     if (defined($path)) {
-	# Try absolute path name.
+	# Try absolute path name, but only eval it if the
+        # transformation from module path to autosplit.ix path
+        # succeeded!
+	my $replaced_okay;
 	if ($is_macos) {
 	    (my $malldir = $calldir) =~ tr#/#:#;
-	    $path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:autosplit.ix#s;
+	    $replaced_okay = ($path =~ s#^(.*)$malldir\.pm\z#$1auto:$malldir:autosplit.ix#s);
 	} else {
-	    $path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#;
+	    $replaced_okay = ($path =~ s#^(.*)$calldir\.pm\z#$1auto/$calldir/autosplit.ix#);
 	}
 
-	eval { require $path; };
+	eval { require $path; } if $replaced_okay;
 	# If that failed, try relative path with normal @INC searching.
-	if ($@) {
+	if (!$replaced_okay or $@) {
 	    $path ="auto/$calldir/autosplit.ix";
 	    eval { require $path; };
 	}

Reply via email to