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

Dear Perl wizards: I need to learn how to import arguments into a module. For example, I want to create a module that stores some stuff for faster later access. I understand that this can be done in different ways, but let's do it with a "static" module. So here is a simplified version of what I want to accomplish;
package main; use cacher "/etc"; my $fstab_wc = cacher::wc("fstab");
This is really a package that is all static. My package itself should do the following: pick up the argument from the use statement (here '/etc') or use a default (say, '/tmp'), and build a hash.
package cacher; use strict; use warnings; use warnings FATAL => qw{ uninitialized }; # larry, this should have b +een part of warnings. ... BEGIN { my %cachehash; my @saved_pkg_args; sub import { ... pick off the arguments, here /etc/ ... ... allow for a default ... ... how?? ... } use File::Glob qw(bsd_glob); foreach my $dir (bsd_glob(@saved_pkg_args, !"GLOB_NOCHECK")) { foreach my $file (bsd_glob("$dir/*")) { $cachehash{"$dir/$file"} = `wc $dir/$file`; } } sub wc { return($cachehash{$_[0]}); } }
so, how do I get the arguments in a simple way?? /iaw4

Replies are listed 'Best First'.
Re: Skeleton For Import to Package?
by almut (Canon) on Jul 28, 2010 at 14:17 UTC
    so, how do I get the arguments

    Inspect @_ in the import routine.

    sub import { my $pkg = shift; # "cacher" in this case my $dir = $_[0] || "/tmp"; setup_cachehash($dir); ... } sub setup_cachehash { ... }
      thanks. I just realized that my error comes from another source. How do I force the "import" to be the first executed statement? ... answer below
      package cacher; use strict; use warnings; use warnings FATAL => qw{ uninitialized }; # larry, this should have b +een part of warnings. use base 'Exporter'; our @EXPORT = ("pdfpagenum"); BEGIN { my $saved_pkg_args="undefined"; sub import { print "import args: ".join("|", @_)."\n"; $saved_pkg_args= $_[1]; print "in import, saved args '$saved_pkg_args'\n"; } sub test { print STDERR "in test, you have saved '$saved_pkg_args'\n +"; } print "this should executed after the import: $saved_pkg_args.\n" } 1;
      I guess I should just call everything I want to be main code from the import statement itself. still strange that import() is not the first thing called.
        How do I force the "import" to be the first executed statement?

        You can't (at least not with the desired arguments), because cacher->import(...) is being called after the module has been required — at which point any code of the module outside of subroutines will already have been run. That's how use works...

        Update: it's maybe worth mentioning that import is not being called at all if you say use cacher ();. If that's an issue in your case, you might want to setup %cachehash with a default directory at the time the module is being required. Then, in case import is being called, just re-initialize %cachehash with the directory specified as the argument to use.  Kind of like this:

        sub import { ... setup_cachehash($dir) if $dir; } sub setup_cachehash { ... } setup_cachehash("/tmp"); # default

        (From a performance point of view, doing things twice is of course suboptimal...)

        P.S.: if you use Exporter in the same package, you probably want to explicitly call its import routine with the appropriate arguments (first arg = your package name), because normally the import method will be inherited from Exporter. In other words, Exporter's import will no longer be called (automatically) when you implement import yourself...