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

Greetings,

O! wise ones, I need your wisdom on the usage of "use":

I have 3 perl modules..

Foo.pm:

package Foo; use strict; sub foo { print "Foo\n"; } 1;
Bar.pm:
package Bar; use strict; use Foo; sub bar { print "Bar\n"; } 1;
Now in a third perl module: Something.pm
package Something; use strict; use Bar; .... Foo::foo; 1;
I expected an error in Something.pm, for calling Foo::foo, when the package "Foo" was not used in package Something. However this works perfectly. I have read the "use" inheritance thread and the perldoc use ..

1. Is this a good practise ?
2. How does this work ?

P.S: I run perl v5.8.5

Replies are listed 'Best First'.
Re: use enlightenment
by jbrugger (Parson) on Mar 08, 2005 at 10:23 UTC
    you load Bar, and in Bar you load Foo.
    the script that loaded Bar, can use Foo now as well,
      And do note that if Foo loaded Bar too, perl wouldn't load it again, because it keeps track of what has been loaded.
Re: use enlightenment
by jkva (Chaplain) on Mar 08, 2005 at 12:44 UTC
    Heh, when I saw the title, I thought it was a package I had not heard of yet.

    If made, it would be something that would tell you everything that you had to know in order to reach enlightenment, or something similar.

    1
      There is no spoon.

      There. No need for a package.

        Also written as:
        use enlightenment; no spoon;

        --
        [ e d @ h a l l e y . c c ]

      I thought it was a module to integrate with Enlightenment...


      --
      Linux, sci-fi, and Nat Torkington, all at Penguicon 3.0
      perl -e 'print(map(chr,(0x4a,0x41,0x50,0x48,0xa)))'
Re: use enlightenment
by cog (Parson) on Mar 08, 2005 at 13:06 UTC
    1. Is this a good practise ?

    Not sure I understand what you mean by "this". Putting things in modules? Yes, probably. Using functions from a package by prepending their package name? Not quite so... Use Exporter to export things properly. See the Exports section of José's Guide for creating Perl modules for more information on how exporting works.

      I don't agree that exporting is always preferable to using symbols with prepended package names. If you export a symbol you are simply creating an alias in the importing module's symbol table. Once you do, you have the possibility of colliding with a symbol exported from another module. Fully-qualified names also tell you where a function comes from, which allows the human reader to look it up more easily. It's a tradeoff for typing convenience.

      Exports aren't automatically visible across modules, either. To take the OP's example:

      package Foo; use strict; use base 'Exporter'; @Foo::EXPORT_OK = qw(foo); sub foo { print "Foo\n"; } 1; package Bar; use strict; use Foo qw(foo); sub bar { foo(); print "Bar\n"; } 1; package Something; use strict; use Bar; # This call will fail. foo();
Re: use enlightenment
by RazorbladeBidet (Friar) on Mar 08, 2005 at 13:04 UTC
    I may be wrong (and believe me, my fellow monks will let me know), but I wouldn't rely on that kind of behavior. Especially if the module is not under your control (e.g. CGI).

    It would be safer to simply use whatever you are referencing. It also serves as a pseudo-comment to the maintainer.
    --------------
    It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
Re: use enlightenment
by ysth (Canon) on Mar 09, 2005 at 09:48 UTC
    I expected an error in Something.pm, for calling Foo::foo, when the package "Foo" was not used in package Something.
    Perl does not keep track of which modules use which other modules. Packages and the subroutines and variables that are in them are global. Once Foo.pm is loaded, Foo::foo() is available everywhere. (use does do an implicit call to the used module's import() method, if it exists, and that import() method can know and record in some fashion which module is doing the use and which module is used; this is usually only used for the used module to export functions into the using package's namespace.)

    No, it's not good practice; modules are supposed to help modularize code, and Something shouldn't be relying on (possibly subject to change) internal details of Bar such as what modules it loads. If you are referencing Foo:: from Something.pm, Something.pm should also use Foo to ensure that it is loaded.