Why does use statement in sub apply globally?
Asked Answered
I

2

7
use WWW::Mechanize;
$mech = new WWW::Mechanize;
$mech->get("http://www.google.com");
$html = HTML::TreeBuilder::XPath->new_from_content($mech->content);
sub test
{
    use HTML::TreeBuilder::XPath;
}

The above code compiles, so the use statement in the sub is being applied globally.

Why does perl do this? It doesn't make any sense.

Imperturbation answered 22/9, 2016 at 1:37 Comment(0)
C
6

use Module; has two effects.

The first is to load the module. Obviously, that has a global effect. One wouldn't want a module to be loaded multiple times if more than one other module uses it.

The second is to call the module's import method. For most modules, this serves to export symbols to the caller's namespace so those functions can be called without qualifying them with a full package name. This obviously affects more than just some sub since noone gives each sub its own namespace. But that's really up to you.

Some module's import method, however, do something quite different. They alter how code is compiled in the lexical scope in which the directive is present. These are called pragmas. use strict; is an example of one. It makes sense to use these modules in a sub. Using use HTML::TreeBuilder::XPath; in a sub, however, makes no sense.

Creekmore answered 22/9, 2016 at 2:19 Comment(0)
C
4

This is what perldoc states:

Because use takes effect at compile time, it doesn't respect the ordinary flow control of the code being compiled. In particular, putting a use inside the false branch of a conditional doesn't prevent it from being processed.

Unfortunately it doesn't give an explanation why it is designed that way. Possible reasons could be:

  • Perl gives you lot's of freedom in many cases (TIMTOWTDI)
  • use inside a subroutine could show your intention that you actually wanna use a module only in a specific place (even when it gets loaded globally)
  • If you (re)move a particular subroutine (which contains a use) later, you don't have to worry about removing unused use's from other places like the top of your script
  • ...

Even though these ideas may sound plausible, I would avoid loading modules in subroutines because it's much clearer to have them all in one location rather than scattered all over the place?

Castellatus answered 22/9, 2016 at 2:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.