Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
There are myriad net explanations of the seldom used "local", "our", & "package" scopings but very little on this "file" scoping

Well, local, our, and package scoped variables (the latter two being pretty much the same anyway, see our) are actually very common, I'd say roughly as common as lexically scoped (my) variables, including at the lexical scope of the file. Admittedly, when writing a normal script one probably types my a lot more often than our, local, or state, but package and dynamic scoping may be being used a lot under the hood, like in the modules one loads. Anyway, if I am understanding your question correctly, you're asking about the my %webpaths variable, and why your three functions in package DataBank can keep using it despite the execution of the file DataBank.pm having already finished?

That's because the three subs refer to it, and so long as there is something that refers to the variable, Perl keeps it around. These "references" are uses of the variable in its lexical scope, as in your case, or lexical variables used by closures, but also references created explicitly, as in my $hashref = \%webpaths. So the answer is yes, this is the intended behavior you can rely on. Maybe this helps:

use warnings; use strict; { package Tracer; sub new { my $c=shift; bless {@_}, $c } sub DESTROY { print "DESTROY ".shift->{name}."\n" } } END { print "END\n" } my $one = Tracer->new(name=>'one'); my $two = Tracer->new(name=>'two'); sub foo { my $three = Tracer->new(name=>'three'); my $four = Tracer->new(name=>'four'); $one->{foo}++; print "end of sub foo\n"; return $three; } my $th = foo(); print "clearing \$th\n"; $th = undef; print "end of main\n"; __END__ end of sub foo DESTROY four clearing $th DESTROY three end of main DESTROY two END DESTROY one

Here, objects of my little class Tracer simply print a message when they are destroyed, which in Perl happens when the last reference to a variable goes away and it is garbage collected. You can see that:

  • $four is declared in the scope of sub foo and only used there, so when the call to sub foo finishes executing, the variable is destroyed,
  • $three is declared in the scope of sub foo, but the reference to the object is returned from the sub, so the outside code now holds a reference to it in $th, so it is not destroyed until we get rid of that reference,
  • $two is declared at the scope of the file, and there are no other references to it, so when the scope of the file ends, it is destroyed,
  • $one is declared at the scope of the file, and since sub foo uses it, it is kept around until global destruction.

Further reading: perlsub, in particular "Private Variables via my()", perlref, and perhaps also perlmod. Perhaps the bit of info you were missing was <update2> the keyword "lexical scope" that "file scope" is not really special, but just another lexical scope. </update2>

Update: Since I glossed over it above, it may be important to note that my has both a compile-time and run-time effect. At compile time, it declares that there is a lexical variable of that name so the compiler knows what that variable is when it sees it in the following code, but the initialization doesn't actually happen until runtime. This means that, for example, in sub bar { my %h; ... }, every call to bar() will create a new hash %h (unlike package variables, as I described in this recent thread). Also made a few small updates to above wording for clarification.


In reply to Re: modular file scoping (updated) by haukex
in thread modular file scoping by Pstack

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-18 02:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found