Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > "use" inside of a subroutine

Reply
Thread Tools

"use" inside of a subroutine

 
 
Jason C
Guest
Posts: n/a
 
      06-22-2012
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?
 
Reply With Quote
 
 
 
 
Rainer Weikusat
Guest
Posts: n/a
 
      06-22-2012
Jason C <(E-Mail Removed)> 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.

 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      06-22-2012
Jason C <(E-Mail Removed)> 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
 
Reply With Quote
 
Xho Jingleheimerschmidt
Guest
Posts: n/a
 
      06-23-2012
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
 
Reply With Quote
 
Jason C
Guest
Posts: n/a
 
      06-23-2012
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.
 
Reply With Quote
 
Jason C
Guest
Posts: n/a
 
      06-23-2012
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?
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      07-07-2012
On Jun 22, 2:54*pm, Ben Morrow <(E-Mail Removed)> wrote:
> Quoth Jason C <(E-Mail Removed)>:
> ...


> > 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
use one subroutine's variable value in another subroutine inside a module. king Perl Misc 5 04-29-2007 06:39 AM
Using open() inside a subroutine imphasing Python 2 02-18-2005 02:23 AM
Using $SIG{"ALRM"} assignment inside a subroutine ... torahul@gmail.com Perl Misc 5 11-11-2004 12:13 AM
Does perl support in/out parameter subroutine? Hon Seng Phuah Perl 1 03-05-2004 03:03 PM
How do I call sort with an anonymous subroutine stored in a hash ?? Casey Perl 3 01-30-2004 03:39 PM



Advertisments