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

I am new to perl and am trying to come up with a main file and bunch of modules to perform some task. When I declare variables as our <variable_name> in one of the module(say a.pm)and when i try to access them in other modules(say b.pm), i am able to do so when I don't use "use strict" and including a.pm in b.pm. So this left me thinking, why do i need to use the exporter module to export the package variables?

Is the reason to use exporter module is to export only a subset of the package variables or is there some other reason for this?

  • Comment on Need of using Exporter to export package variables

Replies are listed 'Best First'.
Re: Need of using Exporter to export package variables
by tobyink (Canon) on Aug 07, 2013 at 07:34 UTC

    As others have pointed out; the Exporter documentation says:

    "Do not export variable names. Just because Exporter lets you do that, it does not mean you should."

    I'll go further than that and add that one of the main reasons that reason exporting package variables is a bad idea is that it means you're using package variables, and package variables are a form of global state.

    Which is not to say that global variables should never be used; sometimes they are a simple, pragmatic way to provide configurability without cluttering an API. For example, Carp's %CarpInternal and $CarpLevel variables. I can even think of an exported package variable that is used to provide a neat API: Test::More's $TODO variable. But these cases are not very common; there are usually better alternatives.

    The basic technique to avoid global state is to make sure that you pass into a function all the data it will need, rather than writing the function so that it fetches some of it's data from some global place.

    So not this:

    our $TaxRate = 0.20; sub add_tax { my ($price) = @_; return $price * (1 + $TaxRate); } print add_tax(50.00), "\n"; # Let's swap to a country with a lower tax rate $TaxRate = 0.15; print add_tax(50.00), "\n";

    Instead do this:

    sub add_tax { my ($price, $TaxRate) = @_; return $price * (1 + $TaxRate); } print add_tax(50.00, 0.20), "\n"; print add_tax(50.00, 0.15), "\n";

    Or if you don't fancy passing the tax rate as a parameter every time, leap into OO programming:

    { package Tax::Zone; sub new { my $class = shift; my $rate = $_[0]; bless \$rate, $class; } sub add_tax { my $self = shift; my $price = $_[0]; return $price * (1 + $$self); } } my $fooland = Tax::Zone->new(0.20); print $fooland->add_tax(50.00), "\n"; my $barland = Tax::Zone->new(0.15); print $barland->add_tax(50.00), "\n";
    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

      Thanks all for the great responses.

Re: Need of using Exporter to export package variables
by kcott (Archbishop) on Aug 07, 2013 at 05:51 UTC

    G'day kbperl,

    Welcome to the monastery.

    There was a discussion related to this last week which you may be interested in: Better way to define global variables. There's code examples, usage advice and documentation links some (or all) of which might be useful to you.

    -- Ken

Re: Need of using Exporter to export package variables
by toolic (Bishop) on Aug 07, 2013 at 01:55 UTC
Re: Need of using Exporter to export package variables
by 2teez (Vicar) on Aug 07, 2013 at 05:07 UTC

    Hi kbperl,

    ...When I declare variables as our <variable_name> in one of the module(say a.pm)and when i try to access them in other modules(say b.pm), i am able to do so when I don't use "use strict" and including a.pm in b.pm...
    And why is that? Because using say: $ModuleA::value_to_get should get the value for you, while strict is enabled and in fact, even when use Exporter; is not used in "ModuleA" this still works. However, it's NOT good practice to even export modules variables to start with.

    Is the reason to use exporter module is to export only a subset of the package variables or is there some other reason for this?
    Adding to what have been said, I would say read Exporter Documentation.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me