"use" inside of a subroutine

Discussion in 'Perl Misc' started by Jason C, Jun 22, 2012.

  1. Jason C

    Jason C Guest

    This is both a "can I" and "should I" question. Meaning, does it work, and if so, is there a reason to not do it?

    I have a variables.lib that I use to hold most of my recurring variables and functions, then "require 'variables.lib' in the Perl scripts.

    What I'm curious about is, can I "use" a module in a subroutine in the variables.lib, or does it have to be "use"d outside of the sub or in the main script?

    Example:

    # variables.lib
    sub copyFile {
    use File::Copy;

    # Use: copyFile('file.txt', 'newfile.txt');
    copy("$basepath/$_[0]", "$basepath/$_[1]")
    or die "Copy failed: $!";
    }

    1;

    That example is just typed up for this post, so please forgive any typos or logic errors. And if this is acceptable, then I would be doing it with several modules, not just File::Copy, this is isn't a module-specific question.

    If "use"ing a module like this inside of a sub is acceptable, then am I correct that it wouldn't be loaded until (or unless) necessary? Or does Perl read ahead and load everything at once, regardless of whether the function or module is actually used?
    Jason C, Jun 22, 2012
    #1
    1. Advertising

  2. Jason C <> writes:

    [...]

    > # variables.lib
    > sub copyFile {
    > use File::Copy;
    >
    > # Use: copyFile('file.txt', 'newfile.txt');
    > copy("$basepath/$_[0]", "$basepath/$_[1]")
    > or die "Copy failed: $!";
    > }


    [...]

    > If "use"ing a module like this inside of a sub is acceptable, then
    > am I correct that it wouldn't be loaded until (or unless) necessary?
    > Or does Perl read ahead and load everything at once, regardless of
    > whether the function or module is actually used?


    Have you considered to 'ask' the documentation first?

    use Module LIST

    Imports some semantics into the current package from the named
    module, generally by aliasing certain subroutine or variable
    names into your package. It is exactly equivalent to

    BEGIN { require Module; Module->import( LIST ); }

    except that Module must be a bareword.

    The 'BEGIN' implies that this code will run during the compilation
    phase as soon as it has been parsed completely.

    Apart from that, I would recommend against 'use of use in
    subroutines': This doesn't really do anything other than an ordinary
    'use Something' (AFAIK) but 'hides' external depedencies in a place
    people usually wouldn't expect them.
    Rainer Weikusat, Jun 22, 2012
    #2
    1. Advertising

  3. Jason C <> wrote:
    >What I'm curious about is, can I "use" a module in a subroutine in the variables.lib, or does it have to be "use"d outside of the sub or in the main script?


    You _can_ use a "use" inside of a sub, but the effect is the same(*) as
    if you would put it outside of the sub, because "use" is evaluated at
    compile time.
    Further details see "perldoc -f use"

    jue

    *: except for increased obscurity
    Jürgen Exner, Jun 23, 2012
    #3
  4. On 06/22/2012 02:24 PM, Jason C wrote:
    > This is both a "can I" and "should I" question. Meaning, does it work, and if so, is there a reason to not do it?
    >
    > I have a variables.lib that I use to hold most of my recurring variables and functions, then "require 'variables.lib' in the Perl scripts.


    A recurring variable? Is that like a constant? Any why not name your
    thingie variables.pl or variables.pm, so people would recognize it?


    > What I'm curious about is, can I "use" a module in a subroutine in the variables.lib, or does it have to be "use"d outside of the sub or in the main script?
    >
    > Example:
    >
    > # variables.lib
    > sub copyFile {
    > use File::Copy;
    >
    > # Use: copyFile('file.txt', 'newfile.txt');
    > copy("$basepath/$_[0]", "$basepath/$_[1]")
    > or die "Copy failed: $!";
    > }
    >
    > 1;
    >
    > That example is just typed up for this post, so please forgive any typos or logic errors. And if this is acceptable, then I would be doing it with several modules, not just File::Copy, this is isn't a module-specific question.


    I do that often with peculiar modules that probably only serve a purpose
    in the context of one function. That way if I copy the function to
    somewhere else, the "use" of the module comes with it.

    But I wouldn't consider File::Copy to be peculiar, and so would just
    throw it up near the top of the module.

    >
    > If "use"ing a module like this inside of a sub is acceptable, then am I correct that it wouldn't be loaded until (or unless) necessary? Or does Perl read ahead and load everything at once, regardless of whether the function or module is actually used?
    >


    No, it is loaded at compile time.

    Xho
    Xho Jingleheimerschmidt, Jun 23, 2012
    #4
  5. Jason C

    Jason C Guest

    On Friday, June 22, 2012 5:54:19 PM UTC-4, Ben Morrow wrote:
    > It's usual to give Perl libraries (to be loaded with require) a '.pl'
    > extension. It's also better nowadays to write a proper '.pm' module
    > instead.


    Hmph, I didn't know that. These scripts actually date back to about 10 years ago, so I just coded the "libraries" as .lib. It's too much to worry about changing right now, until a Perl update forces my hand :)


    > I am curious as to what a 'recurring variable' is.


    Sorry, but since everyone that replied asked this, then obviously I should have been more clear!

    I meant, variables that are used in all of my scripts. Example:

    $home = "http://www.example.com";
    $imagepath = $home . "/images";

    $basepath = "/home/example";
    $wwwpath = $basepath . "/www";

    $mailprog = "/usr/sbin/sendmail";

    and so on.


    > Not exactly. Perl does exactly what you ask it to do: if you ask it
    > (with 'use') to load a module at compile time, it does that. If you ask
    > it (with 'require') to load a module at runtime, it does that; but you
    > have to realise that 'require' will not export functions. If you want to
    > load a module on demand, you need to do it like this:
    >
    > sub copyFile {
    > require File::Copy;
    >
    > File::Copy::copy(...) or die ...;
    > }
    >
    > Both the 'File::Copy::' prefix and the brackets around the function's
    > argument list are important.


    Just to make sure that I understand, are you saying that I could use require inside of the function instead of use, and the module would NOT be loadeduntil necessary? Thereby making the scripts that do not use that particular function marginally faster than if I had loaded all modules outside of the function?

    If so, is there a difference in the sample you posted, and using import? Example:

    sub copyFile {
    require File::Copy;
    File::Copy->import();

    copy(...) or die ...;
    }

    Oh, and thanks to all of you that have replied. I'm specifically replying to Ben because of the require-import question that was segued in his post, but I do appreciate all of the advice.
    Jason C, Jun 23, 2012
    #5
  6. Jason C

    Jason C Guest

    On Saturday, June 23, 2012 10:58:36 AM UTC-4, Ben Morrow wrote:
    > Well, perhaps. If you're worried about load times you would be better
    > off switching from CGI (if that's what you're using) to FastCGI or
    > something else which uses a persistent Perl interpreter.


    I used to use Speedy CGI, but then the persistent interpreter was slowing down the server. Perl speed really isn't all that critical, though; I'm just in the middle of a re-design, so figured that I should make everything as fast and smooth as I can.


    > > sub copyFile {
    > > require File::Copy;
    > > File::Copy->import();
    > >
    > > copy(...) or die ...;
    > > }

    >
    > That will work, but the brackets are mandatory. If you leave them off,
    > perl will not recognise 'copy' as a function, because it was not
    > imported at compile time.


    Ben mentioned earlier that the brackets are mandatory, but now I realize that I'm not sure which brackets you mean.

    Do you mean the round brackets (parentheses)?

    copy("whatever", "whatever") or die ...;

    Or something else?
    Jason C, Jun 23, 2012
    #6
  7. Jason C

    C.DeRykus Guest

    On Jun 22, 2:54 pm, Ben Morrow <> wrote:
    > Quoth Jason C <>:
    > ...


    > > If "use"ing a module like this inside of a sub is acceptable, then am I
    > > correct that it wouldn't be loaded until (or unless) necessary?

    >
    > This is *not* correct. The module will always be loaded, at the point
    > where the file is required.
    >
    > > Or does Perl read ahead and load everything at once, regardless of
    > > whether the function or module is actually used?

    >
    > Not exactly. Perl does exactly what you ask it to do: if you ask it
    > (with 'use') to load a module at compile time, it does that. If you ask
    > it (with 'require') to load a module at runtime, it does that; but you
    > have to realise that 'require' will not export functions. If you want to
    > load a module on demand, you need to do it like this:
    >
    >     sub copyFile {
    >         require File::Copy;
    >
    >         File::Copy::copy(...) or die ...;
    >     }
    >


    I don't know how the autouse pragma works internally
    but it could be another alternative. That is the
    module's load will be postponed until a function is
    actually used.

    The declaration should also be at the top though for
    the reasons mentioned. (Also there are a couple of
    added caveats in autouse's docs.)

    use autouse File::Copy => qw/copy/;

    --
    Charles DeRykus
    C.DeRykus, Jul 7, 2012
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Dorward
    Replies:
    1
    Views:
    2,100
    Isofarro
    Jun 28, 2003
  2. imphasing

    Using open() inside a subroutine

    imphasing, Feb 18, 2005, in forum: Python
    Replies:
    2
    Views:
    273
    imphasing
    Feb 18, 2005
  3. Replies:
    5
    Views:
    340
  4. Nirvana
    Replies:
    1
    Views:
    712
    Michele Dondi
    Nov 27, 2004
  5. king
    Replies:
    5
    Views:
    170
Loading...

Share This Page