Further chat on #p5p/Freenode today suggests an explaination to this:
If there are multiple possible copies of List/Util.pm and .so available in @INC then it's possible that an older copy is found first.
use Sub::Util;
then skips over those older locations that don't have a Sub/Util.pm and find a later copy that does, which then internally has
require List::Util;
which now finds the *first*, older copy of List/Util.pm which pulls in its own older copy of List/Util.so. That file does not have the Sub::Util:: functions in it.
I believe this behaviour could at least be detected by the attached patch and lead to more obvious error messages.
--
Paul Evans
diff --git a/lib/Scalar/Util.pm b/lib/Scalar/Util.pm
index 3f17d13..f270e32 100644
--- a/lib/Scalar/Util.pm
+++ b/lib/Scalar/Util.pm
@@ -8,7 +8,6 @@ package Scalar::Util;
use strict;
require Exporter;
-require List::Util; # List::Util loads the XS
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
@@ -20,6 +19,9 @@ our @EXPORT_OK = qw(
our $VERSION = "1.41";
$VERSION = eval $VERSION;
+require List::Util; # List::Util loads the XS
+List::Util->VERSION( $VERSION ); # Ensure we got the right XS version (RT#100863)
+
our @EXPORT_FAIL;
unless (defined &weaken) {
diff --git a/lib/Sub/Util.pm b/lib/Sub/Util.pm
index e40cf22..8c3b0f0 100644
--- a/lib/Sub/Util.pm
+++ b/lib/Sub/Util.pm
@@ -8,7 +8,6 @@ use strict;
use warnings;
require Exporter;
-require List::Util; # as it has the XS
our @ISA = qw( Exporter );
our @EXPORT_OK = qw(
@@ -19,6 +18,9 @@ our @EXPORT_OK = qw(
our $VERSION = "1.41";
$VERSION = eval $VERSION;
+require List::Util; # as it has the XS
+List::Util->VERSION( $VERSION ); # Ensure we got the right XS version (RT#100863)
+
=head1 NAME
Sub::Util - A selection of utility subroutines for subs and CODE references