in reply to Re: Exporter/@ISA confusion
in thread Exporter/@ISA confusion

There is no reason to use Moose or any heavy handedness for this. The other side of the coin here is that in the script using your module, you may simply use the constructor by calling it in its fully qualified name space. Once you have your blessed reference, there is no need to export any of the instance methods. For example the script using your new module would work perfectly fine if you omitted anything having to to with @INC or Exporter in the .pm:
use strict; use warnings; use MyClass::A (); my $s = MyClass::A->new(); $s->serve();
The Perl module simply has do look like the following:
use strict; use warnings package MyClass::A; sub new { my $pkg = shift; my $self = {}; return bless $self, $pkg; } sub serve { my $self = shift; # .. do whatevs } 1;
In the past Exporter was used to make it more convenient to load subroutines for use without having to deal with namespaces, but as it turns out using fully qualified namespaces is a really great thing to do. If you create a simple object via module using "traditional" Perl OOP, then you only have to type out the namespace once during construction. After that, the fact that the instance variable is blessed with the namespace means that you don't have to keep telling Perl what to use.

Replies are listed 'Best First'.
Re^3: Exporter/@ISA confusion
by qhen (Acolyte) on Jun 10, 2014 at 08:55 UTC

    Thanks - that's what I needed to know. I've been trying to stick to the "modern" Perl way (ie, following recommendations by chromatic, conway, et al), and also trying to keep things simple and clean without having to resort to Moose, etc.

    I've been using Exporter/@ISA and always wondered whether it was really needed as of Perl 5.8 (admittedly I have not spent the time to study the matter; time I often don't have) - the more syntactic cruft I can cut out, the better. I sometimes look at the relative elegance of Python and wish the same were true for Perl (which I love).

    So, bottom line, I can simply exclude use Exporter; our @ISA = qw(Exporter); when creating a new class and/or inheriting from an existing, but still use:

    our @EXPORT = qw(new serve); our @EXPORT_OK = qw(foo);
    to allow optional/selective exporting of methods.

    UPDATE:

    Someone else commented:

    You need to use use Exporter; in your module to get the @EXPORT array into the calling script/module...

    So, in order to use @EXPORT/@EXPORT_OK, I still need to use Exporter.

      Yes, if you want to export subroutines, you need to use Exporter. The most convenient way to do so is to use

      use Exporter 'import';

      ... which does not need to modify @ISA at all, because all Exporter does is supply a subroutine named import.

      But in most cases, object methods do not need to be exported at all. So neither new nor serve should be exported, because they will always be called on an object (or a class).

        ok, that's probably what I needed to hear.

        I just confirmed this with a test:

        package Test::Class; use strict; use warnings; sub new { my ($className, $config) = @_; my $self = {}; bless $self, $className; $self->{config} = \%{$config}; return $self; } sub doSomething { my ($self, $what) = @_; print $self->{config}->{$what} . "\n";; } 1;

        and the caller:

        #!/usr/bin/env perl use strict; use warnings; use lib '.'; use Test::Class; my $t = Test::Class->new( { name => 'bob', } ); $t->doSomething('name');

        ...no need for noisy Exporter/@ISA nonsense. Nice and clean.

        /me raises tankard!

      This is where TIMTOWTDI. I prefer not exporting anything in my own modules. This forces the user of your module to use the full namespace at least once. Some module authors and users prefer the use Module qw(sub1 sub2) type of idiom, and while I don't mind it as a module user I don't like to enable main:: namespace pollution by providing that as something in my own modules.