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

Greetings good monks,

While reading (and being frustrated by) the Panther book (advanced Perl Programming) I noticed the author employed the following:

package Object Template; require Exporter; @ObjectTemplate::ISA = qw(Exporter); @ObjectTemplate::EXPORT = qw(attributes);
My questions are:

1) package scope lasts until either the end of the inner-most block (if it's defined in a block) or until another package definition is encountered. Since we're pulling in package-code by requiring Exporter, what is the official end of its package scope? there are no package declarations after "require Exporter", nor are there any blocks containing the code "package Exporter" in Exporter.pm. It does have a terminating "1" - does that officially end its scope as a package in the enclosing code above? To me, that must be the case... it would seem preposterous that its package-scope would bleed into any modules that require it.

2) why are we fully-qualifying the @ISA and @EXPORT arrays here (e.g. "@ObjectTemplate::ISA" vs. "@ISA"). Is there ambiguity as to which package they would belong to, otherwise? I've seen plenty of examples in which they are not fully qualified in this way.

3) would we have suffered by use-ing Exporter vs. Require-ing it, as above? Use is a compile-time thing, I know, and also makes the products of Exporter available to us. Even though we don't need to take explicit advantage of those in the example above, are there any other reasons for actively not using "use"?

Thank you,

MatthewFrancis

Replies are listed 'Best First'.
Re: packages and Exporter
by diotalevi (Canon) on Dec 04, 2003 at 19:37 UTC

    I would have written it thusly. base is a core pragma intended for fiddling with requiring and altering @ISA. I didn't say `our @EXPORT` because that immediately limits my code to 5.6.0>= while using vars (another pragma) to declare is backwards compatible.

    package ObjectTemplate; use base 'Exporter'; use vars qw(@EXPORT); @EXPORT = qw( attributes );
Re: packages and Exporter
by Anonymous Monk on Dec 04, 2003 at 19:04 UTC

    1) The scope of a package declaration lasts until the end of the current lexical scope. A file is implicitly a lexical scope.

    2) Full qualification is not needed, those variables will be of the current package anyway. The our declaration is often used these days for declaring such package variables under strict.

    3) To use a module both loads it and calls its import routine. We do need to import anything from Exporter (and it doesn't export anything anyway) so we just require it and set @ISA so that we may access its import routine via inheritance.

Re: packages and Exporter
by simonm (Vicar) on Dec 04, 2003 at 19:52 UTC
    2) why are we fully-qualifying the @ISA and @EXPORT arrays here

    For one thing, it makes it easy to insert a "use strict;" line immediately after the package statement, which is often a good idea.

    Also for 1), as noted elsewhere, each file serves as a separate lexical scope so the package declaration from Exporter doesn't "spill over" into the calling package. And for 3), there's no reason to avoid "use" -- either "use" or "require" would be fine in this context.

      Why would you insert the use strict; after the package instead of before it? What are the advantages of this?

      Thanks,

      xenchu

      Perl has one Great Advantage and one Great Disadvantage:

      It is very easy to write a complex and powerful program in three lines of code.

      ********************************************

      The Needs of the World and my Talents run parallel to infinity.
        Why would you insert the use strict; after the package instead of before it? What are the advantages of this?

        Why not? :-)

        The issue isn't whether the strict declaration is before/after the package declaration. The issue is ensuring that the declaration of the package globals doesn't cause a error when strict is being used.

        Using an explicit package name is one method. Using use vars or our are two others.