in reply to Re: Packages and modules
in thread Packages and modules

The answer to this really depends on what type of module you are writing. For object-oriented modules, passing information to the module usually happens when you first create the object:
my $foo = new Foo("bar"); package Foo; sub new { my $class = shift; my $var = shift; bless \$var, $class; }

Otherwise, it is usual to provide both an import() interface and a variable in the namespace of the module in case the value needs to be changed after the module is first included:
---------(In Foo.pm)------------------ package Foo; sub import { $Foo::var = shift; } ---------(In a different file)-------- use Foo qw(bar); # Sets $Foo::var to "bar" #... $Foo::var = "baz"; # Changes $Foo::var to "baz"

Replies are listed 'Best First'.
Re: Re: Re: Packages and modules
by bart (Canon) on Jan 10, 2003 at 03:10 UTC
    ---------(In Foo.pm)------------------ package Foo; sub import { $Foo::var = shift; }
    No, that's wrong. import() is called as a class method, thus the first argument will be the package name as a string, in this case: "Foo". You have to skip it, first, for example by using shift(), before you can get at the user supplied arguments.

    One major difference between normal subs and class methods, apart from this extra first parameter (more trouble than much else, if you ask me), is that inheritance only works on methods, and not on plain subs. And the workings of Exporter are precisely based on this inheritance, where your package inherits the class method "import" from Exporter. Therefore, for Exporter to work, import() must be a method.

Re: Packages and modules
by Anonymous Monk on Jan 09, 2003 at 20:45 UTC

    The package is not OO at this time.

    If I provide an import interface like you describe wouldn't I usually also need to account for the default import behavior? Would it be possible (simply) to design my own import routine which would do whatever, then invoke the default import method to operate on the remaining "arguments"?

    I'd specifically prefer to set it up so that the value is set when the module is first invoked and can not be changed later.

      There is no "default" import behavior, so the import() example that I used earlier was as much as you needed. The only reason that it is called "import()" is because most people use it either directly or indirectly (via Exporter) for exporting symbols to the caller's namespace. If you want to define your own import() sub without losing the functionality of Exporter, look at the export_to_level() function of Exporter, which would work like this:
      package Foo; use base Exporter; @EXPORT_OK=qw($foo $bar $baz); sub import { $foo = $_[0]; Foo->export_to_level(1, @_); #export symbols to caller }

      No more wizardry needed than that. perldoc'ing Exporter will get you more information if you run into trouble.

      Update: I apologize for not making this clear in the original post, but the above code was not intended to set $foo to the first argument passed when you say "use Foo LIST". Since "use Foo LIST" is roughly equivalent to "BEGIN { require Foo; Foo->import(LIST); }", the first argument to import() is the package name, so $foo should be set to "Foo". Yes, this was intentional. If you instead want to get the first argument, set $foo to $_[1]. If you also want to use Exporter, it is not necessarily a good idea to use shift() to remove first argument, as others have suggested, because this will make bad things happen if you subsequently call "Foo->export_to_level(1, @_);"