1

How to print the elements of a hash that is defined in another file?

file1.pl:

#!/usr/bin/perl
use strict;
use warnings;
our %hash = 
("Quarter" , 25,
 "Dime"    , 10,
 "Nickel"  , 5 );

file2.pl:

#!/usr/bin/perl
use strict;
use warnings;
require "file1.pl"
foreach (sort keys %hash){
print "$hash{$_}\n";
}

Output:

Global symbol "%hash" requires explicit package name.
Global symbol "%hash" requires explicit package name.

Kindly help

Vinod R M
  • 45
  • 8
  • For future reference, select your code, then press Ctrl-K or the appropriate button in the toolbar to make your code look right. – ikegami Mar 27 '13 at 07:30
  • (Ignore my vote to close. The post I mentioned in the close vote has inserted a bug in their answer since yesterday.) – ikegami Mar 27 '13 at 07:37
  • http://stackoverflow.com/questions/4543934/how-to-share-export-a-global-variable-between-two-different-perl-scripts this question looks similar to what you need. –  Mar 27 '13 at 08:28

2 Answers2

2

Modules need a package statement and must end with a true value. (It currently returns a true value, but I like to use an explicit 1;.) It's better to give them the .pm extension.

# MyConfig.pm
package MyConfig;
use strict;
use warnings;
our %hash = (
   "Quarter" => 25,
   "Dime"    => 10,
   "Nickel"  =>  5,
);
1;

Now, if you left it at that, you'd need to use %MyConfig::hash instead of %hash. So we need to export the var from the module to the user's namespace.

# MyConfig.pm
package MyConfig;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT = qw( %hash );
our %hash = (
   "Quarter" => 25,
   "Dime"    => 10,
   "Nickel"  =>  5,
);
1;

So on to the script:

#!/usr/bin/perl
use strict;
use warnings;
use MyConfig;
for (sort keys %hash) {
   print "$hash{$_}\n";
}

use MyConfig; does a require (if necessary) and an import. The latter brings the variables and subs listed in @EXPORT into the current namespace.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks a lot! That will be of great help! – Vinod R M Mar 27 '13 at 07:58
  • The reason you want to use a proper module is so can do `use MyConfig;` from multiple places in your application without problem. It might not be needed in this particular project, but doing `do 'helper.pl' or die $@;` is a bad habit to get into even if it's a couple of lines shorter. TLP's suggestion to use an actual config file format for a config file is a very good idea, though. – ikegami Mar 27 '13 at 08:04
  • I get your point. I got one more doubt. Now If I have to declare a package, Is it necessary that the file be a .pm file? Or any other file format would do? – Vinod R M Mar 27 '13 at 08:06
  • @VinodRM File format? Did you mean "File extension"? Yes, it does matter if you use the `use` keyword. – TLP Mar 27 '13 at 08:10
  • Well, if you changed the extension (e.g. to `.pl`), you'd have to change `use MyConfig;` to `BEGIN { require "MyConfig.pl"; import MyConfig; }` – ikegami Mar 27 '13 at 08:42
  • @ikegami Now, in case my hash is a "hash of hashes", how do i print them? – Vinod R M Mar 28 '13 at 05:18
  • Nested structure, so nested loops. Outer loop iterates over elements of outer hash. Inner loop over the elements of the inner hash. – ikegami Mar 28 '13 at 05:30
  • @ikegami Could you please quote the same with a small example? – Vinod R M Mar 28 '13 at 07:25
  • If you don't know how to iterate over the elements of hash, and you can't look it up, you have some learning to do. – ikegami Mar 28 '13 at 07:42
  • @ikegami I know how to iterate through a hash oh hashes(i.e for a hash defined in the same file). But I am not able to understand how to access the hash from another file and iterate through it and print. Kindly help – Vinod R M Mar 28 '13 at 07:44
  • You say you know how to visit a HoH, and I already showed how to export a variable, so what's the problem? I don't know what you want from me. – ikegami Mar 28 '13 at 07:53
1

Ignoring the fact that the code you posted was many edits away from actually giving the error messages you claimed, your problem is that you do not declare %hash in file2.pl. Since that file uses the strict pragma (which is a good thing), it gives this fatal error. To overcome this, declare the hash:

our %hash;
require 'file1.pl';
#... etc.

However, if you are trying to use require as a means of loading a configuration file, there are many better ways. For example Config::Any.

TLP
  • 66,756
  • 10
  • 92
  • 149
  • @TLP If I declare a hash in file2.pl say, our %hash; how does it get access to the hash defined in file1.pl? – Vinod R M Mar 27 '13 at 07:52
  • @VinodRM They both refer to the same variable, `%main::hash`. If you declared a package, e.g. `package MyConfig` like in ikegami's answer, you could use `%MyConfig::hash` in file1.pl. Which is the explicit package name that the original error message mentioned. – TLP Mar 27 '13 at 08:08