Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

loading modules using 'use'

by angshuman (Novice)
on Jun 30, 2010 at 11:19 UTC ( #847298=perlquestion: print w/replies, xml ) Need Help??
angshuman has asked for the wisdom of the Perl Monks concerning the following question:

Lets say a script has 'use A;' Below is the defn of module A
package A; use strict; our (@ISA,@EXPORT); require Exporter; @ISA = qw(Exporter); @EXPORT = qw( abc ); #................ # Some code here #................ 1;

############################################

While 'use' is compile-time loading, 'require' has run-time loading. but the 'import()' function is provided by the Exporter in run-time itself. So what is the thing which 'use A;' loads in at compile time ? as it does not have the import() method yet so it cannot load in the modules. Can anybod explain me what exactly is going on here ?

Replies are listed 'Best First'.
Re: loading modules using 'use'
by Taulmarill (Deacon) on Jun 30, 2010 at 11:30 UTC
    When you use a module, it not only gets compiled but also executed before the program that uses the module runs. So the require is executed at runtime of module A which happens at compile time of the program.
    Btw. you may want to get a little more creative with your package names. A may be fine, but B is a core module.
      Thanks for the quick response, and suggestion, will keep those in mind. One more thing, consider I modified the code piece to the below mentioned code, where I introduce a BEGIN block. How does that help ?....have noticed that in case of circular inheritence/dependency situations the below mentioned code works, rather than the previous one without BEGIN blocks.
      package A; use strict; our (@ISA,@EXPORT); BEGIN{ require Exporter; @ISA = qw(Exporter); @EXPORT = qw( abc ); } #................ # Some code here #................ 1;
Re: loading modules using 'use'
by jethro (Monsignor) on Jun 30, 2010 at 11:54 UTC

    There is not a universal compile-time in perl. If you execute an eval($somestring) for example, the code inside the eval has a compile-time long after the main program executes.

    use Module is equivalent to the sequence BEGIN { require Module; Module->import( LIST ); }, you probably have already read about this. The BEGIN is the statement that moves any code into "compile-time" to be executed as soon as possible). When you 'use A', your "require Exporter" is already inside a BEGIN and therefore executed at compile-time of your main module. And because the import is after the require (so there is a strict order) in the same BEGIN, the import comes after the require

      Thanks again... What does happen in case of circular inheritance ? Lets say a.pl uses A.pm and B.pm, while A.pm and B.pm in turn uses each other. How can in case of circular dependency/inheritance one of the module may not be loaded completely, that too from another module ? What I mean to say that while 'sub abc'(say) in A.pm is accessible fine from a.pl, it may not be accessible from B.pm. Is there a package based loading going on here ?

        This is what "Programming Perl", the O'Reilly book, has to say about it:

        "When Perl searches for a method, it makes sure that you haven't created a circular inheritance hierarchy. This could happen if two classes inherit from one another, even indirectly through other classes. Trying to be your own great-grandfather is too paradoxical even for Perl, so the attempt raises an exception."

        perl only loads a module once. If you use a Module that is already loaded, it's import function is called, but it is not loaded again.

        You know you shouldn't use B as a module name, because there's a B module that comes with perl, right? (It's best to also avoid A because it makes you want to name the next module B.) If you really want to name a throwaway module with a single letter, call it X (or any other letter except B and O).

Re: loading modules using 'use'
by ikegami (Pope) on Jun 30, 2010 at 16:09 UTC

    There's not a single compile-time. When one says "at compile-time", one means "when the containing unit (statement, block, file) is being compiled". Same goes for run time.

    use A;
    is basically
    BEGIN { require A; A->import(); }

    use statements and BEGIN blocks are executed as soon are they are compiled, so the following happens

    1. use A; is compiled.
    2. use A; is executed. (BEGIN blocks are executed as soon as they are compiled.)
      1. require A; is executed.
        1. If A hasn't previously been loaded,
          1. A is loaded and compiled.
            1. ...
            2. require Exporter; is compiled.
            3. @ISA = qw(Exporter); is compiled.
            4. @EXPORT = qw( abc ); is compiled.
            5. ...
          2. A is executed.
            1. ...
            2. require Exporter; is executed.
              1. If Exporter hasn't previously been loaded,
                1. Exporter is loaded and compiled.
                  1. ...
                  2. sub import { ... } is compiled.
                  3. ...
                2. Exporter is executed.
                  1. ...
            3. @ISA = qw(Exporter); is executed.
            4. @EXPORT = qw( abc ); is executed.
            5. ...
      2. A->import(); is executed.

    As you can see, Exporter is loaded and its import method is compiled before your module's import is called without having to make any modifications.

    (I usually use "ModA" instead of "A" because "B" is the name of an existing module.)

      Hi Monk,

      Thank you so very much for the step-by-step explanation,

      OK, in 2.1.1.1 you say A is loaded and compiled. So, what essentially is the difference between
      A.pm ~~~~~~~~~~ package A; require Exporter; @ISA = (Exporter); @EXPORT = qw(abc); AND A.pm ~~~~~~~~~~ package A; BEGIN{ require Exporter; @ISA = (Exporter); @EXPORT = qw(abc); }
      as irrespective of wheather BEGIN is there A is loaded and compiled, when 'use A' is encountered. But the BEGIN blocks provides a significant improvement in case of circular dependency/inheritance issues. How does the BEGIN block create such a difference then.

        If that's the entire file, there's essentially no difference between those two snippets.

        The BEGIN will affect the order in which those statements will be executed in relation to other statements in the file.

Re: loading modules using 'use'
by biohisham (Priest) on Jun 30, 2010 at 12:44 UTC
    use will let the module export its symbol table into the code where the module is used and @ISA indicates to perl to check the Exporter module for methods it can't find in the current module like import hence a code that uses a module can not import symbols from the module by default unless they are exported or have been marked as OK for exportation. This is mentioned in perldoc use and perldoc require.

    @EXPORT array allows you to add other symbols to be exported.

    Replying to your Re^2: loading modules using 'use' comment

    where I introduce a BEGIN block. How does that help ?
    Help in what sense? Well, The Begin block is run even before the rest of the module file is parsed by perl however, can you clarify a bit on what you mean by 'help'?...



    Excellence is an Endeavor of Persistence. A Year-Old Monk :D .
      By 'help', what I wanted to find was a specific situation where putting the require-an-all statements in a BEGIN block in a package module would come into effect, as in normal conditions both without BEGIN and with BEGIN performs exactly the same.

        I'm unsure if i got exactly what you are asking, but let me give you some examples. Let's start with a fairly common thing:

        use CGI qw/:standard/; print header;

        So far, so simple. Now, what perl is doing here, can also be written like this:

        BEGIN { require CGI; CGI->import( ':standard' ); } print header;

        You'll notice, this gives you the same output as the first example. Now let's see what happens, when we don't use the BEGIN block.

        require CGI; CGI->import( ':standard' ); print header;

        The header is not printed out, if we run this. Activating the warnings gives a few hints to what is going on.

        Unquoted string "header" may clash with future reserved word at test.p +l line 12. Name "main::header" used only once: possible typo at test.pl line 12. print() on unopened filehandle header at test.pl line 12.

        Now what happened here?!? perl doesn't know how to handle header anymore, because at the compile time of the program, the subroutine is not yet known to perl. It gets imported at runtime, since require doesn't do anything at compile time, and perl thinks, handler is supposed to be a file handle.

        Hope this cleared some thing up for you

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://847298]
Approved by BioLion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2018-04-22 18:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?