Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

use and require inside subs

by Anonymous Monk
on Nov 02, 2004 at 23:11 UTC ( #404777=perlquestion: print w/replies, xml ) Need Help??

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

sorry monks, I feel like this is info I should be able to find somewhere but I cant.

I have lots of subroutines, many of which use various modules or other subroutines I've made.

I use require 'myperlsub.pl' to include my subroutines and of course 'use' to include modules. What I would like to do is put 'use' and 'require' statements into my subroutines, since sometimes they will be called from scripts that already use and require the necessary subs and modules and sometimes not.

I've read that 'require' will handle double declarations just fine, but I've also read that I should use 'do myperlsub.pl' instead.

I can't find anything that says one way or the other how 'use' will handle this.

Please advise. Thanks.

Replies are listed 'Best First'.
Re: use and require inside subs
by tachyon (Chancellor) on Nov 02, 2004 at 23:37 UTC

    You seem to be making a distinction between subroutines in .pl files and modules. There is no such distinction. Modules are typically just a collection of subroutines/functions/methods/widgets - call them what you will. See Simple Module Tutorial. Anyway besides suggesting that you put everyting into modules for consistency and simplicity's sake the main difference between use and require is that use does a require PLUS calls the modules import function. Never seen a module with an import() function? That is becaue it is inherited from Exporter Depending on what the module exports by default (in @EXPORT) and what you ask for (in @EXPORT_OK) zero or more functions/subroutines will become available via their unqualified name ie you can call somefunction(). You can *always* call Some::Module::somefunction() by its fully qualified name, regardless of whether or not you have imported it. The only pre-requisite is that you have used or required that module first.

    The other significant difference between use and require is that use happens at compile time. require happens at runtime as Perl stumbles across it. require is almost the same as do (it uses it), except it will search @INC for you. For example you can do (not recommended) this to effectively get very similar results to useing a module:

    do 'd:/perl/lib/Data/Dumper.pm'; Data::Dumper->import(); print Dumper(\@INC,\%INC);

    So what do I personally do? Almost all code is in modules. In a given script/module I will use any other Module I know I will need, and import the functions that always get used. In any given function, if it is possible that a module has not been used and/or the required function imported I will have:

    sub widget { # blah require Some::Module; my $result = Some::Module::somefunction(@args);

    cheers

    tachyon

      I thought I knew this, but why do I put my use statements inside if/then if it happens at compile time?
      use warnings; use strict; my $config; if ($^O eq 'MSWin32') { use Win32::TieRegistry( Delimiter=>"/", ArrayValues=>0 ); # load $config from registry } else { # else load $config from flat files }
      Too tired to think for myself tonight.
        I thought I knew this, but why do I put my use statements inside if/then if it happens at compile time?

        As Tachyon points out, you shouldn't. Or at least, run-time statements won't get executed at compile time, so your code won't do what you want.

        Remember, the use() command has an implicit BEGIN block around it, which forces the statements to be executed at compile time. The statement:

        use module;

        is like writing:

        BEGIN { require "module.pm;" module::import(); }

        So, you have two choices. You can make all the decisions about which code to include at run-time, and use "require" statements.

        As ysth points out, something like the following doesn't actually work, though I initially thought it did.

        use warnings; use strict; my $config; BEGIN { if ($^O eq 'MSWin32') { use Win32::TieRegistry( Delimiter=>"/", ArrayValues=>0 ); # load $config from registry } else { # else load $config from flat files } } # end system specific compile time code

        Since BEGIN blocks and use statements both now happen at "compile time", the above code should work, right? Nope. There's a specifically defined order to how BEGIN blocks execute, and it's not what I had assumed it was.

        Upon a careful reading of the perl module documentation page, (type "perldoc perlmod" to read it), I think I understand how it all works. Comments and corrections are appreciated.

        According to the documentation: A "BEGIN" code block is executed as soon as possible, that is, the moment it is completely defined.

        The documentation doesn't say exactly what "completely defined" means, but I took it to mean when the end of the BEGIN block is reached, when reading sequentially through the code. This implies that code like this:

        BEGIN { print "-one-"; BEGIN { print "-two-"; BEGIN { print "-three-; } # end of block that prints "-three-" } # end of block that prints "-two-" } # end of block that prints "-one-"
        should print "-three-two-one", because the end of the block that prints "-three-" is encountered first, then "-two-", then "-one-". This is what happens when I run it, which implies I'm at least close to right.

        It also means that when you write a BEGIN block with a "use" statement inside it, the end of the use statement gets reached before the end of the BEGIN block. Since a use statment is really an implied BEGIN block, this means it executes first, before the BEGIN block gets a chance to do anything.

        Sorry for any confusion I caused. :-( --
        Ytreq Q. Uiop

Re: use and require inside subs
by Tuppence (Pilgrim) on Nov 02, 2004 at 23:57 UTC
    Personally, I force all of my code to be in modules. For development I sometimes do actual perl code in my .pl scripts, but for the most part my scripts all look like
    use My:Script:Foo; My::Script::Foo->bar()
    This allows me to test all of my scripts by ensuring all of my modules are fully tested, and helps me organise my code by functional units instead of just throwing various and sundry subs into my scripts.
Re: use and require inside subs
by JediWizard (Deacon) on Nov 02, 2004 at 23:37 UTC

    Personally, I avoid ever doing a require 'Something.pl'. If I have a subroutine in a script which I need to use in another script, I put it in a module and use it. The only time I use require to include code is when I need to dynamically include something at run time.

    As I understand it, use is a compile time directive, and will have the same effect whether it is inside a subroutine that is called repeatedly, or at the top of the script or file.

    May the Force be with you
Re: use and require inside subs
by kiat (Vicar) on Nov 02, 2004 at 23:41 UTC
    You can also use autouse
    # Main script use autouse Somemodule => qw(func1 func2); main_script_func { func1(); }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://404777]
Approved by ikegami
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2019-12-14 02:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?