Require Class::C3::XS if a compiler is available
Peter Rabbitson [Fri, 6 Apr 2012 15:17:34 +0000 (17:17 +0200)]
.gitignore
ChangeLog
DEV_README [deleted file]
MANIFEST.SKIP
Makefile.PL
lib/Class/C3.pm
t/00_load.t
t/37_mro_warn.t
t/40_no_xs.t [new file with mode: 0644]

index dd1d571..fa8b17c 100644 (file)
@@ -2,7 +2,8 @@
 !.gitignore
 Makefile*
 !Makefile.PL
-META.yml
+META.*
+MYMETA.*
 blib
 build
 inc
index 4b3efb3..7237763 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 Revision history for Perl extension Class::C3.
 
+    - Require Class::C3::XS on 5.8 perls if a working compiler is found
+
 0.23 Sat, Jun 19, 2010
     - Fix various documentation problems (Martin Becker).
 
diff --git a/DEV_README b/DEV_README
deleted file mode 100644 (file)
index 532d886..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-Please package this dist using Perl < 5.9.5, so that the deps show up in META.yml
index d861de0..839cd78 100644 (file)
@@ -4,6 +4,7 @@
 ~$
 \.bak$
 ^MANIFEST\.SKIP$
+^MYMETA\.
 CVS
 \.svn
 \.DS_Store
index 25eb38f..9de5dd2 100644 (file)
@@ -1,23 +1,48 @@
-use inc::Module::Install 0.75;
+use warnings;
+use strict;
 
+use 5.006002;
+use inc::Module::Install 1.06;
+
+perl_version   '5.006002';
 name           'Class-C3';
 all_from       'lib/Class/C3.pm';
 
-# Class::C3 under 5.9.5+ has no deps
-if($] < 5.009_005) {
-    test_requires 'Test::More'    => '0.47';
+test_requires 'Test::More' => '0.47';
 
-    feature 'XS Speedups', 'Class::C3::XS' => '0.07';
+# needed by the PP version only, have them installed
+# regardless of XS availability or perl version
+# (for fatpacking and whatnot)
+requires 'Algorithm::C3' => '0.07';
+requires 'Scalar::Util'  => '0';
 
-    # Would like to disable these if they answer yes above too ...
-    requires 'Algorithm::C3' => '0.06';
-    requires 'Scalar::Util'  => '1.10';
-}
+# XS not interesting after mro is cored
+requires 'Class::C3::XS'  => '0.13'
+  if $] < 5.009_005 and can_xs();
+
+test_requires 'Devel::Hide' => 0
+  if is_smoker();
+
+if($Module::Install::AUTHOR) {
+  # compiler detection, goes into META
+  configure_requires 'ExtUtils::MakeMaker' => '6.52';
+  configure_requires 'ExtUtils::CBuilder'  => '0.27';
 
-# Rebuild README for maintainers
-if(-e 'MANIFEST.SKIP') {
-    system("pod2text lib/Class/C3.pm >README");
+  # Rebuild README for maintainers
+  system("pod2text lib/Class/C3.pm >README");
 }
 
-auto_provides;
 WriteAll;
+
+if ($Module::Install::AUTHOR) {
+  @{Meta->{values}{requires}} = grep
+    { $_->[0] !~ /^ (?: Class::C3::XS | Devel::Hide ) $/x }
+    @{Meta->{values}{requires}}
+  ;
+  print "Regenerating META with XS/test requires excluded\n";
+  Meta->write;
+}
+
+sub is_smoker {
+  return ( $ENV{AUTOMATED_TESTING} && ! $ENV{PERL5_CPANM_IS_RUNNING} && ! $ENV{RELEASE_TESTING} )
+}
index 2af5370..eea78b0 100644 (file)
@@ -14,17 +14,27 @@ BEGIN {
         $C3_IN_CORE = 1;
         require mro;
     }
-    else {
-        eval "require Class::C3::XS";
-        my $error = $@;
-        if(!$error) {
-            $C3_XS = 1;
-        }
-        else {
+    elsif($C3_XS or not defined $C3_XS) {
+        my $error = do {
+            local $@;
+            eval { require Class::C3::XS };
+            $@;
+        };
+
+        if ($error) {
             die $error if $error !~ /\blocate\b/;
+
+            if ($C3_XS) {
+                require Carp;
+                Carp::croak( "XS explicitly requested but Class::C3::XS is not available" );
+            }
+
             require Algorithm::C3;
             require Class::C3::next;
         }
+        else {
+            $C3_XS = 1;
+        }
     }
 }
 
@@ -497,7 +507,7 @@ If your software is meant to work on earlier Perls, use L<Class::C3> as document
 
 =head1 Class::C3::XS
 
-This module will load L<Class::C3::XS> if it's installed and you are running on a Perl version older than 5.9.5.  Installing this is recommended when possible, as it results in significant performance improvements (but unlike the 5.9.5+ core support, it still has all of the same caveats as L<Class::C3>).
+This module will load L<Class::C3::XS> if it's installed and you are running on a Perl version older than 5.9.5.  The optional module will be automatically installed for you if a C compiler is available, as it results in significant performance improvements (but unlike the 5.9.5+ core support, it still has all of the same caveats as L<Class::C3>).
 
 =head1 CODE COVERAGE
 
index 125fbde..7201dac 100644 (file)
@@ -3,9 +3,32 @@
 use strict;
 use warnings;
 
-use Test::More tests => 2;
+use Test::More tests => 4;
 
 BEGIN {
     use_ok('Class::C3');
     use_ok('Class::C3::next');
 }
+
+if ($] > 5.009_004) {
+  ok ($Class::C3::C3_IN_CORE, 'C3 in core');
+  ok (!$Class::C3::C3_XS, 'Not using XS');
+  diag "Fast C3 provided by this perl version $] in core"
+    unless $INC{'Devel/Hide.pm'};
+}
+else {
+  ok (!$Class::C3::C3_IN_CORE, 'C3 not in core');
+
+  if (eval { require Class::C3::XS; Class::C3::XS->VERSION }) {
+    ok ($Class::C3::C3_XS, 'Using XS');
+    diag "XS speedups available (via Class::C3::XS)"
+      unless $INC{'Devel/Hide.pm'};
+  }
+  else {
+    ok (! $Class::C3::C3_XS, 'Not using XS');
+    unless ($INC{'Devel/Hide.pm'}) {
+      diag "NO XS speedups - YOUR CODE WILL BE VERY SLOW. Consider installing Class::C3::XS";
+      sleep 3 if -t *STDIN or -t *STDERR;
+    }
+  }
+}
index f6a8966..1963a84 100644 (file)
@@ -23,7 +23,7 @@ BEGIN
 
     # Remove symbols from respective tables, and
     # remove from INC, so we force re-evaluation
-    foreach my $class qw(Class::C3 MRO::Compat) {
+    foreach my $class (qw(Class::C3 MRO::Compat)) {
         my $file = $class;
         $file =~ s/::/\//g;
         $file .= '.pm';
diff --git a/t/40_no_xs.t b/t/40_no_xs.t
new file mode 100644 (file)
index 0000000..1b0ac3b
--- /dev/null
@@ -0,0 +1,48 @@
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+  plan skip_all => "PP tests not applicable for this perl $]"
+    if $] > 5.009_004;
+
+  plan skip_all => "All tests already executed in PP mode"
+    unless eval { require Class::C3::XS };
+
+  plan skip_all => "Devel::Hide required for this test"
+    unless eval { require Devel::Hide };
+}
+
+use Config;
+use IPC::Open2 qw(open2);
+
+# for the $^X-es
+$ENV{PERL5LIB} = join ($Config{path_sep}, @INC);
+
+# rerun the tests under the assumption of pure-perl
+my $this_file = quotemeta(__FILE__);
+
+for my $fn (glob("t/*.t")) {
+  next if $fn =~ /${this_file}$/;
+
+  local $ENV{DEVEL_HIDE_VERBOSE} = 0;
+  my @cmd = (
+    $^X,
+    '-MDevel::Hide=Class::C3::XS',
+    $fn
+  );
+
+  # this is cheating, and may even hang here and there (testing on windows passed fine)
+  # if it does - will have to fix it somehow (really *REALLY* don't want to pull
+  # in IPC::Cmd just for a fucking test)
+  # the alternative would be to have an ENV check in each test to force a subtest
+  open2(my $out, my $in, @cmd);
+  while (my $ln = <$out>) {
+    print "   $ln";
+  }
+
+  wait;
+  ok (! $?, "Exit $? from: @cmd");
+}
+
+done_testing;