"use" inside of a subroutine

J

Jason C

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?
 
R

Rainer Weikusat

[...]
# 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.
 
J

Jürgen Exner

Jason C said:
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
 
X

Xho Jingleheimerschmidt

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
 
J

Jason C

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.
 
J

Jason C

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.

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?
 
C

C.DeRykus

Quoth Jason C <[email protected]>:
...

This is *not* correct. The module will always be loaded, at the point
where the file is required.


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/;
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,765
Messages
2,569,568
Members
45,042
Latest member
icassiem

Latest Threads

Top