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
views:
67answers:
3First 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
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)
Variables need to belong to a package in order for them to be exportable. If you declare your hash with our
rather than my
, the script using the module will be able to access the hash using its fully-qualified name: %test1::hash
.
To export symbols even more conveniently, you can use Exporter.
# The module.
package Bubb;
use strict;
use warnings;
use base qw(Exporter); # As of Perl 5.10: `use parent ...`
our @EXPORT_OK = qw(bar %fubb);
sub bar { 'bar' }
our %fubb = (fizz => 1, buzz => 2);
1;
# The script.
use Bubb qw(bar %fubb);
That said, it is often advisable to avoid such exporting of variables and all of the problems that go with global variables.
# The module.
# Basically the same as above, except this:
our @EXPORT_OK = qw(bar fubb);
sub fubb {
return fizz => 1, buzz => 2;
}
# The script.
use Bubb qw(bar fubb);
my %fubb = fubb();