perlperl-moduledata-dumper

Conditional load of Data::Dumper::Simple not working


I'm using Data::Dumper and Data::Dumper::Simple (DD and DDS) to print hashes in a verbose mode of a script, and I want to be able to share it with others who may not have those modules installed, so I'm checking that they're loaded.

Without checking for modules successfully loading, a MWE of how I would load and use them is:

use strict;
use warnings;

use Data::Dumper;
use Data::Dumper::Simple;
$Data::Dumper::Sortkeys = 1;

my %testHash=();

warn Dumper(\%testHash);

Which prints:

$testHash = {};

Using the method described here to first check that the modules are loaded, and only use Dumper methods if they are, I rewrote my code as:

use strict;
use warnings;


my $dumperLoaded = 1;
my $rc;

$rc = eval
{
    require Data::Dumper;
    Data::Dumper->import();
    1;
};
if(!$rc)
{
    print "Data::Dumper not found\n";
    $dumperLoaded = 0;
}

$rc = eval
{
    require Data::Dumper::Simple;
    Data::Dumper::Simple->import();
    1;
};
if(!$rc)
{
    print "Data::Dumper::Simple not found\n";
    $dumperLoaded = 0;
}
if($dumperLoaded){
    $Data::Dumper::Sortkeys = 1;
}

my %testHash=();

if($dumperLoaded){
    warn Dumper(\%testHash);
}

And my output is now:

Name "Data::Dumper::Sortkeys" used only once: possible typo at temp.pl line 51.
$VAR1 = {};

Now the hash dump does not show the variable name testHash, as if DDS did not load. However, my script did not complain that it was unable to load DDS. I can replicate this in my first MWE by commenting out use Data::Dumper::Simple;.

My question: Why is the second version of my script, with the check for module load, printing like only DD, and not DDS loaded?

Bonus question: what is the correct way to set SortKeys in a conditional module loading scenario like this?

Thanks.


Solution

  • Data::Dumper::Simple is a source filter. Source filters must be loaded during Perl's compile-phase, or they will not do their job on any of the source code in the script.

    This might work (not tested) works:

    my $dumperLoaded;
    BEGIN { 
        $dumperLoaded = eval "use Data::Dumper::Simple;1" ||
                        eval "use Data::Dumper;1";
    }