develooper Front page | perl.perl5.porters | Postings from June 2012

Re: for inclusion in core: Config::Perl::V

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
June 19, 2012 09:04
Subject:
Re: for inclusion in core: Config::Perl::V
Message ID:
20120619160421.GH18528@plum.flirble.org
On Mon, Jun 18, 2012 at 07:04:11PM +0100, Nicholas Clark wrote:
> On Mon, Jun 18, 2012 at 01:55:31PM -0400, David Golden wrote:
> > On Mon, Jun 18, 2012 at 1:50 PM, Nicholas Clark <nick@ccl4.org> wrote:
> > > But for current and future perls, I *really* don't think that we should be
> > > adding a module that shells out to the current Perl. The entire output of
> > > perl -V is now generated *in Perl space* by Config::_V. Most of the values
> > > needed already exposed by public subroutines in Config, such as
> > > Config::compile_date(). I think that the correct approach is to expose
> > > whatever else is needed, and have Config::Perl::V avoid shelling out if it
> > > doesn't need to.
> > 
> > At the time it was written a couple years ago, I believe there was no
> > perl-space access to certain values compiled in, which is why Tux
> > wrote it in the first place at the request of CPAN Testers.  For
> > smokers, we really need a module that works on current and historical
> > perl's to give the most complete view of the configuration of the
> > perl.  I fully support replacing the shell-out code for modern perls
> > that don't need it, but the module will still need to shell out for
> > legacy perls regardless.
> 
> Yes, sorry, wasn't clear. I should have been clearer that I realise that
> we have to do that for "non-current [Pp]erl". It's pretty useless without
> it.

I was thinking of something like the appended patch. It uses the routines in
Config where present, and the existing code that uses system to call perl -V
where the are not. There's also a test that forces the uses of the `$^X -V`
code to make sure that the two don't get out of sync. (Which I know works,
because initially they weren't)

Tested on that branch, 5.14.0, 5.12.0 and 5.8.9

It's pushed as the head of the branch nicholas/configpm
I don't think I've quite managed to match Merijn's coding style.

Nicholas Clark

commit 996978124d77fbe89e5291e2c83001271111c04f
Author: Nicholas Clark <nick@ccl4.org>
Date:   Tue Jun 19 17:32:14 2012 +0200

    Config::Perl::V::myconfig can avoid `$^X -V` on 5.14.0 and later.
    
    On 5.14.0 and later the Config module has subroutines that provide all the
    data contained within perl -V, so there's no need to shell out to $^X to get
    it.
    
    Also add a test that forces Config::Perl::V::myconfig to shell out, to check
    consistency between the two approaches.

diff --git a/cpan/Config-Perl-V/V.pm b/cpan/Config-Perl-V/V.pm
index b088226..f6520c0 100644
--- a/cpan/Config-Perl-V/V.pm
+++ b/cpan/Config-Perl-V/V.pm
@@ -8,7 +8,7 @@ use warnings;
 use Config;
 use Exporter;
 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
-$VERSION     = "0.15";
+$VERSION     = "0.15_01";
 @ISA         = ("Exporter");
 @EXPORT_OK   = qw( plv2hash summary myconfig signature );
 %EXPORT_TAGS = (
@@ -273,18 +273,30 @@ sub myconfig
     my %args = ref $args eq "HASH"  ? %$args :
                ref $args eq "ARRAY" ? @$args : ();
 
-    #y $pv = qx[$^X -e"sub Config::myconfig{};" -V];
-    my $pv = qx[$^X -V];
-       $pv =~ s{.*?\n\n}{}s;
-       $pv =~ s{\n(?:  \s+|\t\s*)}{ }g;
-
-    #print $pv;
-
     my $build = { %empty_build };
-    $pv =~ m{^\s+Built under (.*)}m                and $build->{osname} = $1;
-    $pv =~ m{^\s+Compiled at (.*)}m                and $build->{stamp}  = $1;
-    $pv =~ m{^\s+Locally applied patches:\s+(.*)}m and $build->{patches} = [ split m/\s+/, $1 ];
-    $pv =~ m{^\s+Compile-time options:\s+(.*)}m    and map { $build->{options}{$_} = 1 } split m/\s+/, $1;
+
+    # 5.14.0 and later provide all the information without shelling out
+    my $stamp = eval {Config::compile_date()};
+    if (defined $stamp) {
+	$stamp =~ s/^Compiled at //;
+	$build->{osname} = $^O;
+	$build->{stamp} = $stamp;
+	$build->{patches} = [Config::local_patches()];
+	$build->{options}{$_} = 1
+	    foreach Config::bincompat_options(), Config::non_bincompat_options();
+    } else {
+	#y $pv = qx[$^X -e"sub Config::myconfig{};" -V];
+	my $pv = qx[$^X -V];
+           $pv =~ s{.*?\n\n}{}s;
+           $pv =~ s{\n(?:  \s+|\t\s*)}{ }g;
+
+	#print $pv;
+
+	$pv =~ m{^\s+Built under (.*)}m                and $build->{osname} = $1;
+	$pv =~ m{^\s+Compiled at (.*)}m                and $build->{stamp}  = $1;
+	$pv =~ m{^\s+Locally applied patches:\s+(.*)}m and $build->{patches} = [ split m/\s+/, $1 ];
+	$pv =~ m{^\s+Compile-time options:\s+(.*)}m    and map { $build->{options}{$_} = 1 } split m/\s+/, $1;
+    }
 
     my @KEYS = keys %ENV;
     my %env  =
diff --git a/cpan/Config-Perl-V/t/10_base.t b/cpan/Config-Perl-V/t/10_base.t
index 4f24d73..38c1b93 100644
--- a/cpan/Config-Perl-V/t/10_base.t
+++ b/cpan/Config-Perl-V/t/10_base.t
@@ -5,7 +5,7 @@ use warnings;
 
 BEGIN {
     use Test::More;
-    my $tests = 7;
+    my $tests = 9;
     unless ($ENV{PERL_CORE}) {
 	require Test::NoWarnings;
 	Test::NoWarnings->import ();
@@ -22,3 +22,14 @@ for (qw( build environment config inc )) {
     ok (exists $conf->{build},			"Has build entry");
     }
 is (lc $conf->{build}{osname}, lc $conf->{config}{osname}, "osname");
+
+SKIP: {
+    # Test that the code that shells out to perl -V and parses the output
+    # gives the same results as the code that calls Config::* routines directly.
+    skip "This perl doesn't provide perl -V in the Config module", 2
+	unless defined &Config::compile_date;
+    eval 'no warnings "redefine"; sub Config::compile_date {return undef}';
+    is (Config::compile_date(), undef, "Successfully overriden compile_date");
+    is_deeply(Config::Perl::V::myconfig, $conf,
+	      "perl -V parsing code produces same result as the Config module");
+}

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About