4.7. The local OperatorYou might consider this next section a giant footnote, but then we couldn't have footnotes on footnotes, so we decided to put it up in the main text. Skip over this text on first reading, and pop right on down to Section 4.8, "Variable-length Parameter Lists". You won't need any of it to do the exercises or write Perl code for a long time. But someone invariably asks us in class something like "What is that local thing I see in some programs?" so we're including what we normally say as an aside in class for your enjoyment and edification. Occasionally, mostly in older code or older Perl books, you'll see the local operator used instead of my. It often looks much the same as my: sub max { local($a, $b) = @_; # looks a lot like my if ($a > $b) { $a } else { $b } } But local is misnamed, or at least misleadingly named. Our friend Chip Salzenberg says that if he ever gets a chance to go back in a time machine to 1986 and give Larry one piece of advice, he'd tell Larry to call local by the name "save" instead.[110] That's because local actually will save the given global variable's value away, so it will later automatically be restored to the global variable. (That's right: these so-called "local" variables are actually globals!) This save-and-restore mechanism is the same one we've already seen twice now, in the control variable of a foreach loop, and in the @_ array of subroutine parameters.
What local actually does, then, is to save away a copy of the variable's value in a secret place (called the stack). That value can't be accessed, modified, or deleted[111] while it is saved. Then local sets the variable to an empty value (undef for scalars, or empty list for arrays), or to whatever value is being assigned. When Perl returns from the subroutine,[112] the variable is automatically restored to its original value. In effect, the variable was borrowed for a time and given back (hopefully) before anyone noticed that it was borrowed.
4.7.1. The Difference Between local and myBut what if the subroutine called another subroutine, one that did notice that the variable was being borrowed by local? For example: $office = "global"; # Global $office &say( ); # says "global", accessing $office directly &fred( ); # says "fred", dynamic scope, # because fred's local $office hides the global &barney( ); # says "global", lexical scope; # barney's $office is visible only in that block sub say { print "$office\n"; } # print the currently visible $office sub fred { local($office) = "fred"; &say( ); } sub barney { my($office) = "barney"; &say( ); } First, we call the subroutine &say, which tells us which $office it sees -- the global $office. That's normal. But then we call Fred's subroutine. Fred has made his own local $office, so he has actually changed the behavior of the &say subroutine; now it tells us what's in Fred's $office. We can't tell whether that's what Fred wanted to do or not without understanding the meaning of his code. But it's a little odd. Barney, however, is a little smarter, as well as being shorter, so he uses the shorter (and smarter) operator, my. Barney's variable $office is private, and Barney's private $office can't be accessed from outside his subroutine, so the &say subroutine is back to normal; it can see only the global $office. Barney didn't change the way &say works, which is more like what most programmers would want and expect. Now, if you're confused about these two operators at this point, that's to be expected. But any time that you see local, think "save," and that may help. In any new code, just use my, since my variables (lexical variables) are faster than globals -- remember, so-called local variables are really globals -- and they'll work more like the traditional variables in other modern programming languages. But when you're maintaining someone else's old code, you can't necessarily change every local to my without checking upon whether the programmer was using that save-and-restore functionality. Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|