in reply to how to get Config values into a hash

Note that Config is not a module that reads configuration files, nor is it the base of the Config:: namespace, the latter being the CPAN modules that typically do read configuration files, like Config::Tiny.

Config is "all the information that was available to the Configure program at Perl build time ... Shell variables from the config.sh file (written by Configure) are stored in the readonly-variable %Config, indexed by their names." So in other words, it's the perl build configuration, which is fixed for each build of Perl at compile time.

The four functions (not methods) that you mention, myconfig, config_sh, config_vars, and config_re, are basically just alternate ways to get information out of Config. In the example code you showed, my $archname = $Config{'archname'}; does not work because you're only requesting those four functions to be exported from Config, but not the %Config hash. So you don't need to "import the values from the myconfig() method into a hash", that's %Config.

You can either just use the module in the basic fashion, where %Config is exported by default:

use Config; my $archname = $Config{'archname'}; print "<$archname>\n";

Or, if you do want to export functions from the module, you need to request the export of %Config explicitly:

use Config qw/%Config config_vars/; my $archname = $Config{'archname'}; print "<$archname>\n"; config_vars("archname","version");

Replies are listed 'Best First'.
Re^2: how to get Config values into a hash
by Aldebaran (Curate) on Oct 17, 2018 at 00:17 UTC

    Thx, Haukex, you've been instrumental in helping me to disambiguate Config situations in such nodes as Re^5: redacting from config hash and node Re^3: redacting from config hash. I hope this isn't a three strikes, you're out scenario, as I fanned on this one pretty hard. I was unaware that this Config was stamped when the user's perl install was made. It's been revealing for me to poke around in this space as a guy who knows some C. I wanted to see if I could read Config.pm, so typed

    locate Config.pm >1.txt

    I might have had 20 candidates with many interesting features on their own right, but I think I narrowed it down to 3 that look like the Config.pm that gets used.

    diff /usr/lib/x86_64-linux-gnu/perl/5.26.1/Config.pm /usr/lib/x86_64-l +inux-gnu/perl-base/Config.pm >2.txt diff /usr/lib/x86_64-linux-gnu/perl/5.26.1/Config.pm /usr/lib/x86_64-l +inux-gnu/perl/cross-config-5.26.1/Config.pm >3.txt diff /usr/lib/x86_64-linux-gnu/perl-base/Config.pm /usr/lib/x86_64-lin +ux-gnu/perl/cross-config-5.26.1/Config.pm >5.txt

    They weren't different from each other except for path. So I try to add functionality to a script to organize and probe these values. My next attempt fell apart when I tried to use Data::Dumper. What's more when I tried to work up the example from Data::Dumper, I couldn't get anywhere. I was able to cobble together a path for one of the Config.pm's using Path::Tiny and slurp it in. It's not horrendously long like some of this output, but to save the monastery's collective scrollfingers, I'll list the script and put abridged output between readmore tags:

    $ cat 4.tk.pl #!/usr/bin/perl -w use 5.011; use utf8; use Config qw/%Config config_vars/; use lib "1.&#1087;&#1089;&#1099;/template_stuff"; use utils1 qw/print_hash/; my $archname = $Config{'archname'}; print "<$archname>\n"; say "---------------"; config_vars( "archname", "version", "libpath", "perl", "scriptdir", "s +itearchexp" ); say "---------------"; my $ref_Config = \%Config; print Dumper $ref_Config; # print() on unopened filehandle Dumper # print Dumper $Config; # Variable "$Config" is not imported print_hash($ref_Config); say "---------------"; use Path::Tiny; my ($archlibexp, $version) = ($Config{archlibexp},$Config{version}); my $arch_path = path($archlibexp)->parent; say "arch_path is $arch_path"; my $path_to_Config = path($arch_path,$version, "Config.pm"); my @lines = $path_to_Config->lines; say "lines are @lines"; say "---------------"; my $ref2_Config = \%Config::Config; print Dumper $ref2_Config; say "---------------"; use ExtUtils::MakeMaker::Config; say $Config{installbin}; say "---------------"; $Data::Dumper::Sortkeys = \&my_filter; my $foo = { map { (ord, "$_$_$_") } 'I'..'Q' }; say "foo is %$foo"; # print Dumper $foo; # print() on unopened filehandle Dumper print_hash($foo); my $bar = { %$foo }; my $baz = { reverse %$foo }; print Dumper [ $foo, $bar, $baz ]; sub my_filter { my ($hash) = @_; # return an array ref containing the hash keys to dump # in the order that you want them to be dumped return [ # Sort the keys of %$foo in reverse numeric order $hash eq $foo ? (sort {$b <=> $a} keys %$hash) : # Only dump the odd number keys of %$bar $hash eq $bar ? (grep {$_ % 2} keys %$hash) : # Sort keys in default order for all other hashes (sort keys %$hash) ]; } $

    How did I lose my grip on Data::Dumper so as not to be able to even work up the example code?

    With 1000's of values in this hash, would I find a variable that contained the path that I think is probable for being the one actually used when during use Config ();? Not really. Output then source:

    #!/usr/bin/perl -w use 5.011; use utf8; use Config qw/%Config config_vars/; use lib "1.&#1087;&#1089;&#1099;/template_stuff"; use utils1 qw/print_hash/; use Path::Tiny; my ( $archlibexp, $version ) = ( $Config{archlibexp}, $Config{version} + ); my $arch_path = path($archlibexp)->parent; say "arch_path is $arch_path"; my $path_to_Config = path( $arch_path, $version, "Config.pm" ); my @lines = $path_to_Config->lines; # say "lines are @lines"; this works say "---------------"; for ( keys %Config ) { next if ($Config{$_} eq undef); if ( $Config{$_} =~ m%/usr/lib/x86_64-linux-gnu/perl% ) { say "$_ matched: $Config{$_}"; } }

    My question here is how does perl decide which Config.pm it uses?

    Thank you for your comments, haukex; I've been following your webperl development and have gotten good initial results that I'm building on.

      print Dumper $ref_Config; # print() on unopened filehandle Dumper

      Looks like you're missing use Data::Dumper; at the top of the script. The error message is a little confusing because Perl is trying to interpret that print as Indirect Object Syntax (print FILEHANDLE LIST).

      Other than that, looks like you've figured out @INC, and I already pointed out %INC, which will give you the location of the file that was actually loaded.

        print FILEHANDLE LIST

        Thx haukex for the precise explanation. I like to finish my threads with working code, for myself and presumably others who will search the net for why Data::Dumper doesn't work unless you 'use' it. They give a pretty good example here, and I wish that all modules would give example code snippets:

        $ ./1.dd.pl $VAR1 = [ { '81' => 'QQQ', '80' => 'PPP', '79' => 'OOO', '78' => 'NNN', '77' => 'MMM', '76' => 'LLL', '75' => 'KKK', '74' => 'JJJ', '73' => 'III' }, { '75' => 'KKK', '79' => 'OOO', '77' => 'MMM', '81' => 'QQQ', '73' => 'III' }, { 'III' => '73', 'JJJ' => '74', 'KKK' => '75', 'LLL' => '76', 'MMM' => '77', 'NNN' => '78', 'OOO' => '79', 'PPP' => '80', 'QQQ' => '81' } ]; $ cat 1.dd.pl #!/usr/bin/perl -w use 5.011; use Data::Dumper; $Data::Dumper::Sortkeys = \&my_filter; my $foo = { map { (ord, "$_$_$_") } 'I'..'Q' }; my $bar = { %$foo }; my $baz = { reverse %$foo }; print Dumper [ $foo, $bar, $baz ]; sub my_filter { my ($hash) = @_; # return an array ref containing the hash keys to dump # in the order that you want them to be dumped return [ # Sort the keys of %$foo in reverse numeric order $hash eq $foo ? (sort {$b <=> $a} keys %$hash) : # Only dump the odd number keys of %$bar $hash eq $bar ? (grep {$_ % 2} keys %$hash) : # Sort keys in default order for all other hashes (sort keys %$hash) ]; } $
      My question here is how does perl decide which Config.pm it uses?

      I think I solved my own question here. When perl looks for Config.pm it starts at the top of @INC and keeps on going until it finds a match. I conjecture that it's guaranteed that there is one at the ultimate path with perl-base:

      $ ./2.cf.pl </usr/lib/x86_64-linux-gnu/perl/5.26> --------------- /home/bob/perl5/lib/perl5/x86_64-linux-gnu-thread-multi /home/bob/perl +5/lib/perl5 /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /us +r/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/s +hare/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 / +usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base path is /usr/lib/x86_64-linux-gnu/perl/5.26/Config.pm stat is File::stat=ARRAY(0x55f122748b70) $VAR1 = bless( [ 2054, 6591373, 33188, 1, 0, 0, 0, 3372, 1539824438, 1531923663, 1532749911, 4096, 8 ], 'File::stat' ); path is /usr/lib/x86_64-linux-gnu/perl-base/Config.pm stat is File::stat=ARRAY(0x55f122ad48c0) $VAR1 = bless( [ 2054, 6591655, 33188, 1, 0, 0, 0, 3373, 1539712704, 1531923663, 1532749916, 4096, 8 ], 'File::stat' ); $ cat 2.cf.pl #!/usr/bin/perl -w use 5.011; use utf8; use Config qw/%Config config_vars/; use Path::Tiny; use Data::Dumper; my $insarchname = $Config{'installarchlib'}; print "<$insarchname>\n"; say "---------------"; say "@INC"; foreach (@INC) { my $path1 = path( $_, "Config.pm" ); if ( -f $path1 ) { my $stat = $path1->stat; say "path is $path1"; say "stat is $stat"; say Dumper $stat; } } $