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

Hi all, I'm trying to create my first module with a function which build a hash cointaining some words but I'm getting some error whose solution I can't find. This is the module:
package MyTools; use strict; BEGIN{ use Exporter (); use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = 0.01; @ISA = qw (Exporter); @EXPORT = qw (); @EXPORT_OK = qw (loadwords); %EXPORT_TAGS = (); } sub loadwords { my @words = qw(a able about above across actually after again all) +; foreach (@words) { my $some_words{$_} = "1"; } } 1; __END__
When I code the same function into a Perl script, I get no errors and it can be used correctly. However, when I "use" the previous module and this script:
#!/usr/bin/perl -w use strict; use MyTools qw(loadwords); my %somewords2; # load the words from the module &loadwords; # load the words using the function &loadwords2; print "'all' is one of my words\n" if $some_words{'all'}; print "'all' is one of my words\n" if $somewords2{'all'}; sub loadwords2 { my @words2 = qw(a able about above across actually after again all +); foreach (@words2) { $somewords2{$_} = "1"; } }
I get a error message:
syntax error at MyTools.pm line 16, near "$some_words{" Compilation failed in require at ./cosa.pl line 3. BEGIN failed--compilation aborted at ./cosa.pl line 3.
What am I doing wrong? I guess I'm not exporting any variable. Any help? Please, open my eyes ;-) Thanks a lot in advance.
Res publica non dominetur.

Replies are listed 'Best First'.
Re: Creating hashes into a module.
by broquaint (Abbot) on Feb 20, 2004 at 11:57 UTC
    That code is broken regardless of whether it's in a module or a stand-alone script. The problem lying at
    foreach (@words) { my $some_words{$_} = "1"; }
    The problem is that you're trying to declare a lexical element of the hash %some_words, which, firstly, hasn't been declared (not necessarily a problem, but still something to be concerned with) and secondly is illegal (as perl only has lexical variables, not lexical hash elements (but dynamic hash elements are possible with local, but that doesn't apply in this case)).

    What you want is to declare the hash and have it exported e.g

    @EXPORT = qw/ loadwords %somewords /; use vars '%somewords'; ## in the loadwords function for(@words) { $somewords{$_} = "1"; }
    This is sort of hash initialisation is more idiomatically done with a single map statement e.g
    %somewords = map { $_ => 1 } @words;
    For more information on exporting and modules see. Exporter and perlmod.
    HTH

    _________
    broquaint

Re: Creating hashes into a module.
by borisz (Canon) on Feb 20, 2004 at 10:59 UTC
    replace
    # wrong line foreach (@words) { my $some_words{$_} = "1"; }
    with
    foreach (@words) { $some_words{$_} = "1"; }
    Boris
      Fixed, but it doesn't work as I need :-( How can I access from the script to the hash %some_words created in the module?
      Res publica non dominetur.
        If you like to export all into the callers namespace put
        @EXPORT = qw (loadwords %some_words);
        into your module code. But this is not a good idea. what about returning a reference to the new created %somewords?
        sub loadwords { my @words = qw(a able about above across actually after again all) +; my %some_words; foreach (@words) { $some_words{$_} = "1"; } return \%some_words; }
        Boris
Re: Creating hashes into a module.
by pelagic (Priest) on Feb 20, 2004 at 11:31 UTC
    Consult perldoc perlmod
    Study the 'scope' of the variables you use ...
    There's no other way; you must understand this first.
    pelagic

    -------------------------------------
    I can resist anything but temptation.
      You're right, I'm already perldocing ;-) Thanx!
      Res publica non dominetur.
        browsing through perldoc ... perlsub has interesting paragraphs about my, local etc.
        pelagic

        -------------------------------------
        I can resist anything but temptation.