Plankton has asked for the wisdom of the Perl Monks concerning the following question:

Friends,

I was try to come up with a way of loading a hash from a file with require ... here's what I am doing:
$ cat HoH.pl #!/usr/bin/perl -w use strict; use Data::Dumper; require 'hash'; print Dumper(%HoH); $ cat hash my $HoH = { 'HASH_1' => { item_a => "abc", item_b => "123", item_c => "blue", }, 'HASH_2' => { item_a => "xyz", item_b => "789", item_c => "white", }, 'HASH_3' => { item_a => "ijk", item_b => "3.14", item_c => "yellow", } }; $ ./HoH.pl Global symbol "%HoH" requires explicit package name at ./HoH.pl line 5 +. Execution of ./HoH.pl aborted due to compilation errors.
What am I doing wrong?

Thanks!

Plankton: 1% Evil, 99% Hot Gas.

Replies are listed 'Best First'.
Re: using require as c like #include?
by Coruscate (Sexton) on Jan 19, 2004 at 23:51 UTC

    $ cat HoH.pl #!/usr/bin/perl -w use strict; use Data::Dumper; our $HoH = do 'hash'; print Dumper($HoH); $ cat hash { 'HASH_1' => { item_a => "abc", item_b => "123", item_c => "blue", }, 'HASH_2' => { item_a => "xyz", item_b => "789", item_c => "white", }, 'HASH_3' => { item_a => "ijk", item_b => "3.14", item_c => "yellow", } } $ ./HoH.pl $VAR1 = { 'HASH_3' => { 'item_b' => '3.14', 'item_c' => 'yellow', 'item_a' => 'ijk' }, 'HASH_2' => { 'item_b' => '789', 'item_c' => 'white', 'item_a' => 'xyz' }, 'HASH_1' => { 'item_b' => '123', 'item_c' => 'blue', 'item_a' => 'abc' } };

      Wow! That's it! Thanks!

      Plankton: 1% Evil, 99% Hot Gas.
Re: using require as c like #include?
by davido (Cardinal) on Jan 20, 2004 at 07:12 UTC
    If all you're trying to do is bring in a stored hash, why not do it the easy way:

    use strict; use warnings; use Storable; use Data::Dumper; my $h_ref = { 'This' => 1, 'That' => 2 }; store $h_ref, 'myfile'; my $stored_hash = retrieve('myfile'); print Dumper $stored_hash;


    Dave

Re: using require as c like #include?
by Roger (Parson) on Jan 19, 2004 at 23:40 UTC
    # -- HoH.pl -- #!/usr/bin/perl -w use strict; use Data::Dumper; use hash; print Dumper($HoH); # refer to the imported variable # -- hash.pm -- package hash; our @EXPORT = '$HoH'; # export your variable $HoH use base "Exporter"; our $HoH = { 'HASH_1' => { item_a => "abc", item_b => "123", item_c => "blue", }, 'HASH_2' => { item_a => "xyz", item_b => "789", item_c => "white", }, 'HASH_3' => { item_a => "ijk", item_b => "3.14", item_c => "yellow", } }; 1;

    However there is a problem with the above approach, what happens if another package also exports $HoH? There is a possibility of name collision. I would rather encapsulate the HoH variable inside a hash object instead:

    # -- HoH.pl -- #!/usr/bin/perl -w use strict; use Data::Dumper; use hash; my $h = new hash; print Dumper($h->HoH); # -- hash.pm -- package hash; my $HoH = { 'HASH_1' => { item_a => "abc", item_b => "123", item_c => "blue", }, 'HASH_2' => { item_a => "xyz", item_b => "789", item_c => "white", }, 'HASH_3' => { item_a => "ijk", item_b => "3.14", item_c => "yellow", } }; sub new { my $class = shift; bless {}, $class; } sub HoH { # my $class = shift; $HoH # the HoH method returns hash reference } 1;

    Update: Or using do as demonstrated by Coruscate below, of course.

Re: using require as c like #include?
by jweed (Chaplain) on Jan 19, 2004 at 23:31 UTC
    First off, you'll need to use use instead of require beacuse require doesn't import. Then, you'll have to create an import function to bring the Hash into the main package, which requires some experience with symbol tables and the like. Check out Of Symbol Tables and Globs, Exporter, and use for more info.



    Code is (almost) always untested.
    http://www.justicepoetic.net/
Re: using require as c like #include?
by Zed_Lopez (Chaplain) on Jan 19, 2004 at 23:57 UTC

    There are a couple of problems here. my means lexical scoping, which means the my $HoH in hash isn't supposed to be accessible anywhere else. $HoH in hash is a hashref; then the main code expects a hash.

    You'd be better off with use, but it's not necessary. Starting hash like this:

    package hash; %HoH = ( 'HASH_1' => {

    and using this for the main routine would work:

    #!/usr/bin/perl -w use strict; use Data::Dumper; require 'hash'; print Dumper($hash::HoH);

    or, you could have hash assign directly to the main namespace:

    $main::HoH = { 'HASH_1' => { item_a => "abc",

    and then

    #!/usr/bin/perl -w use strict; use Data::Dumper; require 'hash'; print Dumper($main::HoH);

    (These are examples of what is possible, not what's recommended.)

Re: using require as c like #include?
by mce (Curate) on Jan 20, 2004 at 10:47 UTC
    I prefer the kiss solution :-)
    Package Cfg::Hash; $Cfg::Hash::HoH={ A => 1 }; 1;
    and in the main code:
    use Cfg::Hash; # provided it can be found warn $Cfg::Hash::HoH->{A};
    So, just fully qualify your hashes, and it is very easy to find where they are defined. (and strict will not complain).
    ps: this is similar to the our approach.
    ---------------------------
    Dr. Mark Ceulemans
    Senior Consultant
    BMC, Belgium
Re: using require as c like #include?
by flounder99 (Friar) on Jan 20, 2004 at 13:16 UTC
    First, there is an error in your example. You are creating $HoH but are dumping %HoH.

    Besides that what is happening is that the code brought in by require is in it's own scope. So the variables declared with my go a way when you leave that scope. This is what our is for. If you are using an older (pre 5.6) version of perl you can use vars

    $ cat HoH.pl use strict; use Data::Dumper; our $HoH; require 'hash'; print Dumper($HoH);
    or
    use strict; use Data::Dumper; use vars qw/ $HoH /; require 'hash'; print Dumper($HoH);
    Either way you will just have to drop the my in hash (or also declare it our if you are using the first example.)

    --

    flounder