Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The trite answer is that you have to use <code>local</code> because <code>my *FH</code> is a syntax error.</p> <p>The "right" (but not very enlightening) answer is that you're doing it wrong. You should be using lexical filehandles and the three-argument form of <code>open</code> instead.</p> <pre><code>sub newopen { my $path = shift; my $fh; open($fh, '&lt;', $path) or do { warn "Can't read file '$path' [$!]\n"; return; } return $fh; } </code></pre> <p>To really answer <em>why</em> requires an explanation of the difference between lexical and global variables and between a variable's scope and its duration.</p> <p>A variable's scope is the portion of the program where its name is valid. Scope is a static property. A variable's duration, on the other hand, is a dynamic property. Duration is the time during a program's execution that the variable exists and holds a value.</p> <p><code>my</code> declares a lexical variable. Lexical variables have a scope from the point of declaration to the end of the enclosing block (or file). You can have other variables with the same name in different scopes without conflict. (You can also re-use a name in overlapping scopes, but don't do that.) The duration of lexical variables is managed thorugh reference counting. So long as there is at least one reference to a variable the value exists, even if the name isn't valid within a particular scope! <code>my</code> also has a runtime effect -- it allocates a <strong>new</strong> variable with the given name.</p> <p><code>local</code> is a bit different. It operates on global variables. Global variables have a global scope (the name is valid everywhere) and a duration of the entire life of the program. What <code>local</code> does is make a temporary change to the <em>value</em> of a global variable. This is sometimes referred to as "dynamic scoping." The change starts at the point of the <code>local</code> declaration and persists until the end of the enclosing block after which the old value is restored. It's important to note that the new value is not restricted to the block -- it is visible everywhere (including called subroutines). Reference counting rules still apply, so you can take and keep a reference to a localized value after the change has expired.</p> <p>Back to the example: <code>*FH</code> is a global variable. More accurately it's a "typeglob" -- a container for a set of global variables. A typeglob contains a slot for each of the basic variable types (scalar, array, hash) plus a few other things. Historically, Perl used typeglobs for storing filehandles and <code>local</code>-izing them helped ensure that they didn't clobber each other. Lexical variables don't have typeglobs which is why saying <code>my *FH</code> is a syntax error.</p> <p>In modern versions of Perl lexical variables can and should be used as filehandles instead. And that brings us back to the "right" answer.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload