Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a hash available in another module

Tags:

perl

for Ex : 
package test1 ; 

my %hash = ( a=> 10 , b => 30 ) ;

1;

in Script : 

use test1 ;

print %hash ;  # How to  make this avilable in script without sub
like image 412
Tree Avatar asked Nov 28 '22 18:11

Tree


2 Answers

Good programming practice prescribes that you do not allow foreign code to mess with a module's data directly, instead they must go through an intermediary, for example an accessor routine.

TIMTOWTDI, with and without exporting. The Moose example appears quite long, but this one also allows setting data as opposed to just reading it from Test1, where the other three examples would need quite some additional code to handle this case.


unsugared

Module

package Test1;
{
    my %hash = (a => 10, b => 30);
    sub member_data { return %hash; }
}
1;

Program

use Test1 qw();
Test1::member_data; # returns (a => 10, b => 30)

Moose

Module

package Test1;
use Moose;
has 'member_data' => (is => 'rw', isa => 'HashRef', default => sub { return {a => 10, b => 30}; });
1;

Program

use Test1 qw();
Test1->new->member_data; # returns {a => 10, b => 30}
# can also set/write data!  ->member_data(\%something_new)

Sub::Exporter

Module

package Test1;
use Sub::Exporter -setup => { exports => [ qw(member_data) ] };

{
    my %hash = (a => 10, b => 30);
    sub member_data { return %hash; }
}
1;

Program

use Test1 qw(member_data);
member_data; # returns (a => 10, b => 30)

Exporter

Module

package Test1;
use parent 'Exporter';

our @EXPORT_OK = qw(member_data);

{
    my %hash = (a => 10, b => 30);
    sub member_data { return %hash; }
}
1;

Program

use Test1 qw(member_data);
member_data; # returns (a => 10, b => 30)
like image 153
daxim Avatar answered Dec 10 '22 02:12

daxim


First thing is that you can't declare it using "my", as that declares lexical, not package, variables. Use our to let you refer to a package variable and assign it the value you want. Then in your other package, prefix the name of the variable with the name of the first package. use isn't like a C# using statement, as it doesn't import symbols from the other package, it just makes them available.

Something like this should work to demonstrate:

use strict;
use warnings;

package test1; 

our %hash = ( a=> 10 , b => 30 ) ;

package test2;

print $test1::hash{a} ; #prints 10
like image 28
dsolimano Avatar answered Dec 10 '22 03:12

dsolimano