Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: 'require/use' scoping

by brian_d_foy (Abbot)
on Jan 29, 2008 at 15:26 UTC ( [id://664910]=note: print w/replies, xml ) Need Help??


in reply to 'require/use' scoping

[ Whenever someone asks you the difference between require and use, point them to the use entry in perlfunc. Not only will they get the right answer, but they'll learn how to use the docs. In this case, the OP wants to know about what require does and how it does it. Again, perlfunc has the answer. :)]

Packages or namespaces are not scopes! This week I've seen a few people mention that, but it's not true and I don't know where people ever see that. Scopes are either blocks of code or the file, which has an implicit scope around all of its contents. The package pragma is scoped, but any symbol table work it does is not.

These two are equivalent and there's nothing else special going on. It's not just a run-/compile-time thing. The use also implies an import.

use Foo; BEGIN { require Foo; Foo->import; }

Curiously, the answer in perlfaq8 on "What's the difference between use and require" is crap, so now I must go fix it. And so it has come to pass:

What's the difference between require and use?

Perl runs require statement at run-time. Once Perl loads, compiles, and runs the file, it doesn't do anything else. The use statement is the same as a require run at compile-time, but Perl also calls the import method for the loaded package. These two are the same:

use MODULE qw(import list); BEGIN { require MODULE; MODULE->import(import list); }

However, you can suppress the import by using an explicit, empty import list. Both of these still happen at compile-time:

use MODULE (); BEGIN { require MODULE; }

Since use will also call the import method, the actual value for MODULE must be a bareword. That is, use cannot load files by name, although require can:

require "lib/Foo.pm"; # no @INC searching!

See the entry for use in perlfunc for more details.

Now, the other part of the OP's question is what require is actually doing. Again, it's right in perlfunc. This code is directly from the entry on require and shows exactly what you would have to do on your own to recreate its behaviour:

sub require { my ($filename) = @_; if (exists $INC{$filename}) { return 1 if $INC{$filename}; die "Compilation failed in require"; } my ($realfilename,$result); ITER: { foreach $prefix (@INC) { $realfilename = "$prefix/$filename"; if (-f $realfilename) { $INC{$filename} = $realfilename; $result = do $realfilename; last ITER; } } die "Can't find $filename in \@INC"; } if ($@) { $INC{$filename} = undef; die $@; } elsif (!$result) { delete $INC{$filename}; die "$filename did not return true value"; } else { return $result; } }

That little snippet is already assuming that a bareword has been turned into a filename, and doesn't do portable path construction, but it's the mechanics that count. Notice the do to actually run the code.

--
brian d foy <brian@stonehenge.com>
Subscribe to The Perl Review

Replies are listed 'Best First'.
Re^2: 'require/use' scoping ("scope")
by tye (Sage) on Jan 29, 2008 at 15:49 UTC
    Packages or namespaces are not scopes! This week I've seen a few people mention that, but it's not true and I don't know where people ever see that. Scopes are either blocks of code or the file, which has an implicit scope around all of its contents. The package pragma is scoped, but any symbol table work is does is not.

    The parts of the code where a variable is visible constitutes the scope of the variable. Lexical variables have a lexical scope and you've enumerated the lexical scopes in Perl (except that lexical scopes are subsets of those because they begin on the statement after the variable is declared). The scope for a(n unqualified) package variable is the package. This is not a lexical scope but it is a scope. local effects dynamic scope which is about the scope of the value rather than the variable (or, more precisely, of an instance of the variable). Dynamic scope is certainly not a lexical scope.

    The scope of the effect of symbol table manipulations is usually the symbol table, that is, the package. The scope of the effect of a lexical pragma is a subset of the lexical scopes that you enumerated, one starting at the statement after the invocation of the pragma (just like for lexical variables).

    - tye        

      Package variables are visible throughout the entire program. They have no scope. Don't confuse the default package with a scope. A default package doesn't limit the extent or effect of a variable. To use "scope" in that sense only confuses people and makes the word useless. In your sense, you could also talk about the "scope" of hash keys. It's not a useful concept when you extend it like that, and that's not it's meaning when you're talking Perl.

      local has nothing to do with the scope of the variable. It deals with the value of the variable during a lexical scope (but not within a lexical scope), and only works on package variables. The variable's value is available outside of its lexical scope (as in subroutines and so on).

      See the entry for package in perlfunc for details.

      Update: Tye, think what you like, but Perl isn't Wikipedia. When you talk about (Update: variable) scope in Perl, the time it makes any sense is in lexical scoping. Any other use of the concept is just wanking. It's not my personal definition: it's how it's used in the Perl documentation, which doesn't have any other (Update: variable) scope to talk about. Despite you're repeated claim about a package variable being scoped, it's just not true. It's always available everywhere in the program. The small matter of syntax about referencing it doesn't matter. As for what local does, don't conflate how it does it behind the scenes with what the feature is. You might also want to read Dominus's Coping with Scoping".

      --
      brian d foy <brian@stonehenge.com>
      Subscribe to The Perl Review
        local has nothing to do with the scope of the variable...(snip)...the time it makes any sense is in lexical scoping...it's how it's used in the perl documentation, which doesn't have any other scope to talk about...(snip)...read Dominus's Coping with Scoping.

        See perldoc -q "dynamic and lexical"

        Also, in Dominus' addendum article Seven Useful Uses of Local there's some stuff on dynamic scoping.

        Update: also (on an unrelated note), in your node above, the comment in this line is incorrect (as pointed out by tye in the CB):

        require "lib/Foo.pm"; # no @INC searching!

        I guess you need to scour the web and literature and implement your new personal definition of "scope" (which appears to only include "lexical scope of variables").

        For example, Wikipedia knows that there are non-lexical types of scope including dynamic scope, that scope can apply to values not just variables, and that "a namespace is a scope". Although Foldoc unfortunately defines scope tersely in a way that implies only lexical scopes but this poor definition is contradicted by its own entries for dynamic scope and lexical scope.

        A namespace is a scope and it does limit the effect of a variable; that's the point. You don't want your choice of variable names to affect the code that doesn't use your namespace. A package variable is limited in scope to only places that reference the owning namespace (either by declaring that they are in that package or by prepending the package name in order to access the variable). You can even access lexical variables outside of their scope if you take extra steps. The scope talks about where a simple $name will work.

        local has nothing to do with the scope of the variable. It deals with the value

        Yeah, that was what I said. But it is more accurate to say that local effects a new instance of a variable (and assigns that instance a new value) that has a dynamic scope. The value of this new instance can be changed but the instance will be destroyed when the program leaves its dynamic scope.

        Update: Brian, think what you want. I heard about dynamic scope because the transition from Perl 4 to Perl 5 was a transition from only supporting dynamic scope to supporting lexical scope. If the authors of some of the Perl documentation now choose to not use "scope" except when talking about lexical scope, then I don't have a problem with that. But the programming world is not the Perl documentation and claiming "a namespace isn't a scope" is untrue. You can claim "the Perl documentation avoids referring to a namespace as a scope, preferring to reserve that term for only lexical scopes". But you don't get to define what the word "scope" means outside of that little world. You can even say "I wouldn't call a package a scope". I don't happen to live in the Perl documentation and care about more than how such chooses to use words.

        You can choose to use a more narrow definition of "scope" and you won't even run into any problems so long as you realize you have narrowed the definition and so avoid boldly declaring what isn't included in your narrowed definition (without qualifiers to denote to others that it is a non-standard usage).

        - tye        

        When you talk about scope in Perl, the time it makes any sense is in lexical scoping. Any other use of the concept is just wanking.

        Well, not quite. I can switch, in any lexical scope, the package. Doing so, as long as the package switch lasts, I can access thingies of that package - subroutines, globs, variables (except file scoped things like my() variables) - without qualifying them. It's a scope! and I can enter and leave it whenever I want! There's more to scopes in perl than just blocks!

        A scope is de- and confined by its boundaries. Do you have a better "synthesis term" for what tye, I and you are saying? If you haven't, putting off those considerations as "wanking" is just... er, can't get an appropriate term right now; have to think about it...

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re^2: 'require/use' scoping
by gnum.prul (Initiate) on Jan 29, 2008 at 16:01 UTC
    Hey Brian!
    The package pragma is scoped, but any symbol table work is does is not.
    This is actually what I was asking about :) Thanks!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://664910]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (1)
As of 2024-04-25 03:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found