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

hi guys,

I have created a script and used common subs in a module, my problem is though I am storing data in two hashes %template and %language to be used in the module, but the hashes arent carried over to the module, I haven't declared them as my or local in the main script so I cant see why not

I know I can pass one across as Module->subroutine("%hash") but not sure about two..any tips?

Replies are listed 'Best First'.
Re: Pass data to a Module
by grep (Monsignor) on Jan 13, 2002 at 06:53 UTC
    It sounds like you want to pass references to hashes. You can look this FAQ up by:
  • perldoc -q pass hash
  • perldoc perlreftut
  • Super Search on PM
    #!/usr/bin/perl use warnings; use strict; my %foo_hash = qw/elmer fudd slyvester cat/; my %bar_hash = qw/bugs bunny tweety bird/; foo(\%foo_hash,\%bar_hash); sub foo { my ($hash1,$hash2) = @_; foreach (keys %$hash1) { print "$_ $$hash1{$_}\n"; } foreach (keys %$hash2) { print "$_ $$hash2{$_}\n"; } }

    Wooohooo this is my 50th post

    grep
    grep> cd pub grep> more beer
Re (tilly) 1: Pass data to a Module
by tilly (Archbishop) on Jan 13, 2002 at 08:02 UTC
    Insert usual lecture on the issues with using globals.

    But sometimes it makes sense to export globals. If you want to, just follow the following template in your module:

    package My::Module; use base 'Exporter'; @EXPORT_OK = qw( $foo some_sub @stuff ); use strict; use vars qw($foo @stuff); # Write your module here, using your variables and # defining functions for export. 1;
    And now in your client script do:
    use strict; use My::Module qw($foo some_sub @stuff); use vars qw($foo @stuff); # etc
    Material you may want to look up. strict.pm and relatives for explanations of the sanity checks, Exporter is being used to export from one package to another, and Dominus' Coping With Scoping to understand why the variables were not being seen as shared in the first place.
(Ovid) Re: Pass data to a Module
by Ovid (Cardinal) on Jan 13, 2002 at 08:11 UTC

    In addition to grep's comments about references, I happened to notice this:

    I haven't declared them as my or local in the main script ...

    What is probably going on is that you are expecting these variables to be global, but you probably haven't taken into account the namespace. This implies to me that you are likely not using strict. I can't prove that (you didn't post your code), but it has been my experience that someone who is unfamiliar with package declarations or who (ab)uses globals is unlikely to be familiar with strict. Please read 'use strict' is not Perl. You may not like what you read, but it will save you grief in the long run. In the meantime, you can follow grep's advice. However, I would make a tiny change to his syntax:

    sub foo { my ($hash1,$hash2) = @_; # cleaner dereference foreach (keys %$hash1) { print "$_ $hash1->{$_}\n"; } # preferred, if you need to access both while ( my ($key, $value) = each %$hash2 ) { print "$key $value\n"; } }

    The first loop uses the arrow syntax to dereference (cleaner, and easier to read, in my opinion) and the second loop uses the each iterator to get at the values (another "clean" method).

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.