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

I have a script (we'll call it test.pl), which "use"s a module (we'll call it my_module.pm).

test.pl is kicked off with some varying arguments provided to it (i.e. different arguments each time it's run), and I would like to share one of these variables with my_module.pm, so that when my_module.pm first gets loaded it'll do something different according to the variable's value.

So, examples of what I have are below:

package my_module; $VERSION = '1.00'; use strict; our $gMessage; sub import { $gMessage = @_; print "Yep, I'm in here ... \n\n"; } &my_sub(); sub my_sub { print $gMessage; }

test.pl looks like this:

#!/usr/bin/perl use strict; use my_module 'xyz'; ... ... ...

In this test.pl, just for an example, I'm just providing a static argument, but in reality it's a varying value.

Nevertheless, what I'm anticipating is that test.pl will "use" my_module, and pass in "xyz" and then the module will print the "Yep, I'm in here" message, followed by "xyz" when it gets to my_sub, which is called when my_module is loaded.

However, I guess I must be misunderstanding something because the "Yep, I'm in here" message never gets printed, and the variable is empty when it gets to my_sub.

Thus, I guess the import sub is never being called, but I thought that by default an import sub is always called, if it exists, when "use"ing a module.

Noting that I don't want to share a variable from the module to the script, but vice-versa, if anyone could shed some light, or suggest a better method, then I'd be grateful. Thanks!

Replies are listed 'Best First'.
Re: Share Variable in Script with a Module
by boftx (Deacon) on Oct 05, 2013 at 00:00 UTC

    I modified your module slightly as follows:

    package my_module; $VERSION = '1.00'; use strict; use Data::Dumper; our $gMessage; sub import { ($gMessage) = @_; print Dumper(\@_); print "Yep, I'm in here ... \n\n"; } &my_sub(); sub my_sub { print "Yep, I'm in here, too ... \n\n"; print $gMessage; } 1;

    And this is the resulting output:

    $ ./testmymodule.pl Yep, I'm in here, too ... $VAR1 = [ 'my_module', 'xyz' ]; Yep, I'm in here ...

    That should clarify why you do not see 'xyz' being printed.

    On time, cheap, compliant with final specs. Pick two.
Re: Share Variable in Script with a Module
by tangent (Parson) on Oct 05, 2013 at 00:11 UTC
    As boftx points out your problem is that my_sub() is called before the import() so your variable is not initialised - if you use warnings it will tell you this. Also, the first argument to import is the class name, so you should shift that first:
    package my_module; $VERSION = '1.00'; use strict; use warnings; our $gMessage; sub import { my $class = shift; $gMessage = shift; print "Yep, I'm in here ...\n\n"; my_sub(); } sub my_sub { print $gMessage; } 1;
    Output:
    Yep, I'm in here ... xyz
      Okay, thank you both. I'll have another try at it tomorrow.

      Okay, that does work, but seems to introduce another problem, which I don't quite understand.

      The test module, and test script, are shown below:

      The module
      package my_testmodule; $VERSION = '1.00'; use strict; use warnings; our $gMessage; undef our @list; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(@list); sub import { my $class = shift; $gMessage = shift; print "Yep, I'm in here ...\n\n"; my_sub(); } # &my_sub; sub my_sub { print "$gMessage\n\n" if ($gMessage); push (@list,'oranges','lemons','apples'); } 1;
      The script
      #!/usr/bin/perl use strict; use warnings; use my_testmodule 'xyz'; print "$list[0]\n\n"; exit;

      Previously, before trying to pass the module anything at all, and thus without the import sub, I would be able to read @list, defined in the module, in test.pl.

      However, now, with the import sub, I'll get an error when running test.pl, "Global symbol "@list" requires explicit package name at test.pl line 8."

      I don't see why this should be, seeing as it appears to be defined and exported properly in the module; in fact nothing to do with @list has changed.

      I did also try referencing @list with the package name, but that doesn't work either.

      Any help/suggestions would be much appreciated. Thanks!

        By defining an import method in your module you are overriding Exporter's own import method so it never gets called and doesn't export your list. To fix that, add the following line:
        sub import { my_testmodule->export_to_level(1, @_); my $class = shift; $gMessage = shift; print "Yep, I'm in here ...\n\n"; my_sub(); }
        See the Exporter module's documentation for more.