📄 perlsub.1
字号:
.Vb 8\& {\& my $secret_val = 0;\& sub gimme_another {\& return ++$secret_val;\& }\& }\& # $secret_val now becomes unreachable by the outside\& # world, but retains its value between calls to gimme_another.Ve.PPIf this function is being sourced in from a separate filevia \f(CW\*(C`require\*(C'\fR or \f(CW\*(C`use\*(C'\fR, then this is probably just fine. If it'sall in the main program, you'll need to arrange for the \f(CW\*(C`my\*(C'\fRto be executed early, either by putting the whole block aboveyour main program, or more likely, placing merely a \f(CW\*(C`BEGIN\*(C'\fRcode block around it to make sure it gets executed before your programstarts to run:.PP.Vb 6\& BEGIN {\& my $secret_val = 0;\& sub gimme_another {\& return ++$secret_val;\& }\& }.Ve.PPSee \*(L"\s-1BEGIN\s0, \s-1UNITCHECK\s0, \s-1CHECK\s0, \s-1INIT\s0 and \s-1END\s0\*(R" in perlmod about thespecial triggered code blocks, \f(CW\*(C`BEGIN\*(C'\fR, \f(CW\*(C`UNITCHECK\*(C'\fR, \f(CW\*(C`CHECK\*(C'\fR,\&\f(CW\*(C`INIT\*(C'\fR and \f(CW\*(C`END\*(C'\fR..PPIf declared at the outermost scope (the file scope), then lexicalswork somewhat like C's file statics. They are available to allfunctions in that same file declared below them, but are inaccessiblefrom outside that file. This strategy is sometimes used in modulesto create private variables that the whole module can see..Sh "Temporary Values via \fIlocal()\fP".IX Xref "local scope, dynamic dynamic scope variable, local variable, temporary".IX Subsection "Temporary Values via local()"\&\fB\s-1WARNING\s0\fR: In general, you should be using \f(CW\*(C`my\*(C'\fR instead of \f(CW\*(C`local\*(C'\fR, becauseit's faster and safer. Exceptions to this include the global punctuationvariables, global filehandles and formats, and direct manipulation of thePerl symbol table itself. \f(CW\*(C`local\*(C'\fR is mostly used when the current valueof a variable must be visible to called subroutines..PPSynopsis:.PP.Vb 1\& # localization of values\&\& local $foo; # make $foo dynamically local\& local (@wid, %get); # make list of variables local\& local $foo = "flurp"; # make $foo dynamic, and init it\& local @oof = @bar; # make @oof dynamic, and init it\&\& local $hash{key} = "val"; # sets a local value for this hash entry\& local ($cond ? $v1 : $v2); # several types of lvalues support\& # localization\&\& # localization of symbols\&\& local *FH; # localize $FH, @FH, %FH, &FH ...\& local *merlyn = *randal; # now $merlyn is really $randal, plus\& # @merlyn is really @randal, etc\& local *merlyn = \*(Aqrandal\*(Aq; # SAME THING: promote \*(Aqrandal\*(Aq to *randal\& local *merlyn = \e$randal; # just alias $merlyn, not @merlyn etc.Ve.PPA \f(CW\*(C`local\*(C'\fR modifies its listed variables to be \*(L"local\*(R" to theenclosing block, \f(CW\*(C`eval\*(C'\fR, or \f(CW\*(C`do FILE\*(C'\fR\-\-and to \fIany subroutinecalled from within that block\fR. A \f(CW\*(C`local\*(C'\fR just gives temporaryvalues to global (meaning package) variables. It does \fInot\fR createa local variable. This is known as dynamic scoping. Lexical scopingis done with \f(CW\*(C`my\*(C'\fR, which works more like C's auto declarations..PPSome types of lvalues can be localized as well : hash and array elementsand slices, conditionals (provided that their result is alwayslocalizable), and symbolic references. As for simple variables, thiscreates new, dynamically scoped values..PPIf more than one variable or expression is given to \f(CW\*(C`local\*(C'\fR, they must beplaced in parentheses. This operator worksby saving the current values of those variables in its argument list on ahidden stack and restoring them upon exiting the block, subroutine, oreval. This means that called subroutines can also reference the localvariable, but not the global one. The argument list may be assigned to ifdesired, which allows you to initialize your local variables. (If noinitializer is given for a particular variable, it is created with anundefined value.).PPBecause \f(CW\*(C`local\*(C'\fR is a run-time operator, it gets executed each timethrough a loop. Consequently, it's more efficient to localize yourvariables outside the loop..PP\fIGrammatical note on \fIlocal()\fI\fR.IX Xref "local, context".IX Subsection "Grammatical note on local()".PPA \f(CW\*(C`local\*(C'\fR is simply a modifier on an lvalue expression. When you assign toa \f(CW\*(C`local\*(C'\fRized variable, the \f(CW\*(C`local\*(C'\fR doesn't change whether its list is viewedas a scalar or an array. So.PP.Vb 2\& local($foo) = <STDIN>;\& local @FOO = <STDIN>;.Ve.PPboth supply a list context to the right-hand side, while.PP.Vb 1\& local $foo = <STDIN>;.Ve.PPsupplies a scalar context..PP\fILocalization of special variables\fR.IX Xref "local, special variable".IX Subsection "Localization of special variables".PPIf you localize a special variable, you'll be giving a new value to it,but its magic won't go away. That means that all side-effects relatedto this magic still work with the localized value..PPThis feature allows code like this to work :.PP.Vb 2\& # Read the whole contents of FILE in $slurp\& { local $/ = undef; $slurp = <FILE>; }.Ve.PPNote, however, that this restricts localization of some values ; forexample, the following statement dies, as of perl 5.9.0, with an error\&\fIModification of a read-only value attempted\fR, because the \f(CW$1\fR variable ismagical and read-only :.PP.Vb 1\& local $1 = 2;.Ve.PPSimilarly, but in a way more difficult to spot, the following snippet willdie in perl 5.9.0 :.PP.Vb 5\& sub f { local $_ = "foo"; print }\& for ($1) {\& # now $_ is aliased to $1, thus is magic and readonly\& f();\& }.Ve.PPSee next section for an alternative to this situation..PP\&\fB\s-1WARNING\s0\fR: Localization of tied arrays and hashes does not currentlywork as described.This will be fixed in a future release of Perl; in the meantime, avoidcode that relies on any particular behaviour of localising tied arraysor hashes (localising individual elements is still okay).See \*(L"Localising Tied Arrays and Hashes Is Broken\*(R" in perl58delta for moredetails..IX Xref "local, tie".PP\fILocalization of globs\fR.IX Xref "local, glob glob".IX Subsection "Localization of globs".PPThe construct.PP.Vb 1\& local *name;.Ve.PPcreates a whole new symbol table entry for the glob \f(CW\*(C`name\*(C'\fR in thecurrent package. That means that all variables in its glob slot ($name,\&\f(CW@name\fR, \f(CW%name\fR, &name, and the \f(CW\*(C`name\*(C'\fR filehandle) are dynamically reset..PPThis implies, among other things, that any magic eventually carried bythose variables is locally lost. In other words, saying \f(CW\*(C`local */\*(C'\fRwill not have any effect on the internal value of the input recordseparator..PPNotably, if you want to work with a brand new value of the default scalar\&\f(CW$_\fR, and avoid the potential problem listed above about \f(CW$_\fR previouslycarrying a magic value, you should use \f(CW\*(C`local *_\*(C'\fR instead of \f(CW\*(C`local $_\*(C'\fR.As of perl 5.9.1, you can also use the lexical form of \f(CW$_\fR (declaring itwith \f(CW\*(C`my $_\*(C'\fR), which avoids completely this problem..PP\fILocalization of elements of composite types\fR.IX Xref "local, composite type element local, array element local, hash element".IX Subsection "Localization of elements of composite types".PPIt's also worth taking a moment to explain what happens when you\&\f(CW\*(C`local\*(C'\fRize a member of a composite type (i.e. an array or hash element).In this case, the element is \f(CW\*(C`local\*(C'\fRized \fIby name\fR. This means thatwhen the scope of the \f(CW\*(C`local()\*(C'\fR ends, the saved value will berestored to the hash element whose key was named in the \f(CW\*(C`local()\*(C'\fR, orthe array element whose index was named in the \f(CW\*(C`local()\*(C'\fR. If thatelement was deleted while the \f(CW\*(C`local()\*(C'\fR was in effect (e.g. by a\&\f(CW\*(C`delete()\*(C'\fR from a hash or a \f(CW\*(C`shift()\*(C'\fR of an array), it will springback into existence, possibly extending an array and filling in theskipped elements with \f(CW\*(C`undef\*(C'\fR. For instance, if you say.PP.Vb 10\& %hash = ( \*(AqThis\*(Aq => \*(Aqis\*(Aq, \*(Aqa\*(Aq => \*(Aqtest\*(Aq );\& @ary = ( 0..5 );\& {\& local($ary[5]) = 6;\& local($hash{\*(Aqa\*(Aq}) = \*(Aqdrill\*(Aq;\& while (my $e = pop(@ary)) {\& print "$e . . .\en";\& last unless $e > 3;\& }\& if (@ary) {\& $hash{\*(Aqonly a\*(Aq} = \*(Aqtest\*(Aq;\& delete $hash{\*(Aqa\*(Aq};\& }\& }\& print join(\*(Aq \*(Aq, map { "$_ $hash{$_}" } sort keys %hash),".\en";\& print "The array has ",scalar(@ary)," elements: ",\& join(\*(Aq, \*(Aq, map { defined $_ ? $_ : \*(Aqundef\*(Aq } @ary),"\en";.Ve.PPPerl will print.PP.Vb 5\& 6 . . .\& 4 . . .\& 3 . . .\& This is a test only a test.\& The array has 6 elements: 0, 1, 2, undef, undef, 5.Ve.PPThe behavior of \fIlocal()\fR on non-existent members of compositetypes is subject to change in future..Sh "Lvalue subroutines".IX Xref "lvalue subroutine, lvalue".IX Subsection "Lvalue subroutines"\&\fB\s-1WARNING\s0\fR: Lvalue subroutines are still experimental and theimplementation may change in future versions of Perl..PPIt is possible to return a modifiable value from a subroutine.To do this, you have to declare the subroutine to return an lvalue..PP.Vb 8\& my $val;\& sub canmod : lvalue {\& # return $val; this doesn\*(Aqt work, don\*(Aqt say "return"\& $val;\& }\& sub nomod {\& $val;\& }\&\& canmod() = 5; # assigns to $val\& nomod() = 5; # ERROR.Ve.PPThe scalar/list context for the subroutine and for the right-handside of assignment is determined as if the subroutine call is replacedby a scalar. For example, consider:.PP.Vb 1\& data(2,3) = get_data(3,4);.Ve.PPBoth subroutines here are called in a scalar context, while in:.PP.Vb 1\& (data(2,3)) = get_data(3,4);.Ve.PPand in:.PP.Vb 1\& (data(2),data(3)) = get_data(3,4);.Ve.PPall the subroutines are called in a list context..IP "Lvalue subroutines are \s-1EXPERIMENTAL\s0" 4.IX Item "Lvalue subroutines are EXPERIMENTAL"They appear to be convenient, but there are several reasons to becircumspect..SpYou can't use the return keyword, you must pass out the value beforefalling out of subroutine scope. (see comment in example above). Thisis usually not a problem, but it disallows an explicit return out of adeeply nested loop, which is sometimes a nice way out..SpThey violate encapsulation. A normal mutator can check the suppliedargument before setting the attribute it is protecting, an lvaluesubroutine never gets that chance. Consider;.Sp.Vb 1\& my $some_array_ref = []; # protected by mutators ??\&\& sub set_arr { # normal mutator\& my $val = shift;\& die("expected array, you supplied ", ref $val)\& unless ref $val eq \*(AqARRAY\*(Aq;\& $some_array_ref = $val;\& }\& sub set_arr_lv : lvalue { # lvalue mutator\& $some_array_ref;\& }\&\& # set_arr_lv cannot stop this !\& set_arr_lv() = { a => 1 };.Ve.Sh "Passing Symbol Table Entries (typeglobs)".IX Xref "typeglob *".IX Subsection "Passing Symbol Table Entries (typeglobs)"\&\fB\s-1WARNING\s0\fR: The mechanism described in this section was originallythe only way to simulate pass-by-reference in older versions ofPerl. While it still works fine in modern versions, the new referencemechanism is generally easier to work with. See below..PPSometimes you don't want to pass the value of an array to a subroutinebut rather the name of it, so that the subroutine can modify the globalcopy of it rather than working with a local copy. In perl you canrefer to all objects of a particular name by prefixing the namewith a star: \f(CW*foo\fR. This is often known as a \*(L"typeglob\*(R", because thestar on the front can be thought of as a wildcard match for all thefunny prefix characters on variables and subroutines and such..PPWhen evaluated, the typeglob produces a scalar value that representsall the objects of that name, including any filehandle, format, orsubroutine. When assigned to, it causes the name mentioned to refer towhatever \f(CW\*(C`*\*(C'\fR value was assigned to it. Example:.PP.Vb 8\& sub doubleary {\& local(*someary) = @_;\& foreach $elem (@someary) {\& $elem *= 2;\& }\& }\& doubleary(*foo);\& doubleary(*bar);.Ve
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -