0

Can some explain how to pass a HASH from a module to main. I've read posts like How to share/export a global variable between two different perl scripts? and understand the basic concept behind it but this is a little different and I can't find any examples.

This module works if called from main, but how do I just pass the hash to main so that I can print in there, instead of printing it from the module. Or so I can write the key values to file or something.

package My::Module;
use strict;
use warnings;

use Exporter;
our @ISA = 'Exporter';
our @EXPORT = qw(get_proc_info);

sub get_proc_info
    {

        my %processor;
        Win32::SystemInfo::ProcessorInfo(%processor);
                for (my $i=0;$i<$processor{NumProcessors};$i++)
                {
                    print "Processor $i\n";
                    print "Processor Name: " . $processor{"Processor$i"}{ProcessorName} . "\n";
                    print "Processor Info: " . $processor{"Processor$i"}{Identifier} . "\n";
                    print "Processor Speed: " . $processor{"Processor$i"}{MHZ} . "MHz\n\n"; 
                }  

    }
Community
  • 1
  • 1

3 Answers3

3

Exporting variables is a bad practice. You can always export a sub that returns the content of the variable, though:

#!/usr/bin/perl
use warnings;
use strict;

{   package HashExport;
    my %hash = ( key => 'value' );

    sub get_hash {
        return %hash
    }
}

use Data::Dumper;
my %imported = HashExport::get_hash();
print Dumper \%imported;
choroba
  • 231,213
  • 25
  • 204
  • 289
1

Return a reference to it.

The module:

package My::Module;

use strict;
use warnings;

use Exporter          qw( import );
use Win32::SystemInfo qw( );

our @EXPORT_OK = qw( get_processors );

sub get_processors {
    my %processors;
    Win32::SystemInfo::ProcessorInfo(%processors);
    return \%processors;
}

1;

The caller:

use My::Module qw( get_processors );

my $processors = get_processors();

for my $i (0 .. $processors->{NumProcessors}-1)
    my $processor = $processors->{"Processor$i"};

    print "Processor $i\n";
    print "Processor Name:  $processor->{ProcessorName}\n";
    print "Processor Info:  $processor->{Identifier}\n";
    print "Processor Speed: $processor->{MHZ} MHz\n"; 
    print "\n";
}

The above already "fixes" some of Win32::SystemInfo::ProcessorInfo's weird interfaces. The following fixes it further:

The module:

package My::Module;

use strict;
use warnings;

use Exporter          qw( import );
use Win32::SystemInfo qw( );

our @EXPORT_OK = qw( get_processors );

sub get_processors {
    my %processors;
    Win32::SystemInfo::ProcessorInfo(%processors);
    return
        map { $processors{"Processor$_"} }
            0 .. $processors{NumProcessors}-1;
}

1;

The caller:

use My::Module qw( get_processors );

my @processors = get_processors();

for my $i (0..$#processors)
    my $processor = $processors[$i];

    print "Processor $i\n";
    print "Processor Name:  $processor->{ProcessorName}\n";
    print "Processor Info:  $processor->{Identifier}\n";
    print "Processor Speed: $processor->{MHZ} MHz\n"; 
    print "\n";
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
1

It depends what you're trying to do

You can use Exporter to export any package identifier. It just happens to be named subroutines that don't need a leading sigil and are always package identifiers

I can create a globally-accessible hash like this

MyStuff.pm

package MyStuff;

use strict;
use warnings 'all';

use Exporter 'import';

our @EXPORT_OK = qw/ %Data /;

our %Data = (
    a => 1,
    b => 2,
    c => 3,
);

1;

And import and use it like this

main.pl

use strict;
use warnings 'all';

use MyStuff '%Data';

use Data::Dump;

dd \%Data;

output

{ a => 1, b => 2, c => 3 }

However any sort of global mutable value lays you open to all sorts of action at a distance bugs. The alternative of writing a global subroutine that returns a reference to a value is really no better at all

Borodin
  • 126,100
  • 9
  • 70
  • 144