summaryrefslogtreecommitdiff
path: root/pod/perlsub.pod
diff options
context:
space:
mode:
Diffstat (limited to 'pod/perlsub.pod')
-rw-r--r--pod/perlsub.pod99
1 files changed, 58 insertions, 41 deletions
diff --git a/pod/perlsub.pod b/pod/perlsub.pod
index 870b2b5af9..1c3a3c0709 100644
--- a/pod/perlsub.pod
+++ b/pod/perlsub.pod
@@ -187,11 +187,12 @@ Synopsis:
my @oof = @bar; # declare @oof lexical, and init it
A "my" declares the listed variables to be confined (lexically) to the
-enclosing block, subroutine, C<eval>, or C<do/require/use>'d file. If
-more than one value is listed, the list must be placed in parens. All
-listed elements must be legal lvalues. Only alphanumeric identifiers may
-be lexically scoped--magical builtins like $/ must currently be localized with
-"local" instead.
+enclosing block, conditional (C<if/unless/elsif/else>), loop
+(C<for/foreach/while/until/continue>), subroutine, C<eval>, or
+C<do/require/use>'d file. If more than one value is listed, the list
+must be placed in parens. All listed elements must be legal lvalues.
+Only alphanumeric identifiers may be lexically scoped--magical
+builtins like $/ must currently be localized with "local" instead.
Unlike dynamic variables created by the "local" statement, lexical
variables declared with "my" are totally hidden from the outside world,
@@ -250,6 +251,49 @@ the expression
is false unless the old $x happened to have the value 123.
+Lexical scopes of control structures are not bounded precisely by the
+braces that delimit their controlled blocks; control expressions are
+part of the scope, too. Thus in the loop
+
+ while (my $line = <>) {
+ $line = lc $line;
+ } continue {
+ print $line;
+ }
+
+the scope of $line extends from its declaration throughout the rest of
+the loop construct (including the C<continue> clause), but not beyond
+it. Similarly, in the conditional
+
+ if ((my $answer = <STDIN>) =~ /^yes$/i) {
+ user_agrees();
+ } elsif ($answer =~ /^no$/i) {
+ user_disagrees();
+ } else {
+ chomp $answer;
+ die "'$answer' is neither 'yes' nor 'no'";
+ }
+
+the scope of $answer extends from its declaration throughout the rest
+of the conditional (including C<elsif> and C<else> clauses, if any),
+but not beyond it.
+
+(None of the foregoing applies to C<if/unless> or C<while/until>
+modifiers appended to simple statements. Such modifiers are not
+control structures and have no effect on scoping.)
+
+The C<foreach> loop defaults to dynamically scoping its index variable
+(in the manner of C<local>; see below). However, if the index
+variable is prefixed with the keyword "my", then it is lexically
+scoped instead. Thus in the loop
+
+ for my $i (1, 2, 3) {
+ some_function();
+ }
+
+the scope of $i extends to the end of the loop, but not beyond it, and
+so the value of $i is unavailable in some_function().
+
Some users may wish to encourage the use of lexically scoped variables.
As an aid to catching implicit references to package variables,
if you say
@@ -422,11 +466,11 @@ Sometimes you don't want to pass the value of an array to a subroutine
but rather the name of it, so that the subroutine can modify the global
copy of it rather than working with a local copy. In perl you can
refer to all objects of a particular name by prefixing the name
-with a star: C<*foo>. This is often known as a "type glob", since the
+with a star: C<*foo>. This is often known as a "typeglob", since the
star on the front can be thought of as a wildcard match for all the
funny prefix characters on variables and subroutines and such.
-When evaluated, the type glob produces a scalar value that represents
+When evaluated, the typeglob produces a scalar value that represents
all the objects of that name, including any filehandle, format or
subroutine. When assigned to, it causes the name mentioned to refer to
whatever "*" value was assigned to it. Example:
@@ -450,14 +494,15 @@ an array. It will certainly be faster to pass the typeglob (or reference).
Even if you don't want to modify an array, this mechanism is useful for
passing multiple arrays in a single LIST, since normally the LIST
mechanism will merge all the array values so that you can't extract out
-the individual arrays. For more on typeglobs, see L<perldata/"Typeglobs">.
+the individual arrays. For more on typeglobs, see
+L<perldata/"Typeglobs and FileHandles">.
=head2 Pass by Reference
-If you want to pass more than one array or hash into a function--or
-return them from it--and have them maintain their integrity,
-then you're going to have to use an explicit pass-by-reference.
-Before you do that, you need to understand references as detailed in L<perlref>.
+If you want to pass more than one array or hash into a function--or
+return them from it--and have them maintain their integrity, then
+you're going to have to use an explicit pass-by-reference. Before you
+do that, you need to understand references as detailed in L<perlref>.
This section may not make much sense to you otherwise.
Here are a few simple examples. First, let's pass in several
@@ -538,34 +583,6 @@ Here we're using the typeglobs to do symbol table aliasing. It's
a tad subtle, though, and also won't work if you're using my()
variables, since only globals (well, and local()s) are in the symbol table.
-If you're passing around filehandles, you could usually just use the bare
-typeglob, like *STDOUT, but typeglobs references would be better because
-they'll still work properly under C<use strict 'refs'>. For example:
-
- splutter(\*STDOUT);
- sub splutter {
- my $fh = shift;
- print $fh "her um well a hmmm\n";
- }
-
- $rec = get_rec(\*STDIN);
- sub get_rec {
- my $fh = shift;
- return scalar <$fh>;
- }
-
-If you're planning on generating new filehandles, you could do this:
-
- sub openit {
- my $name = shift;
- local *FH;
- return open (FH, $path) ? \*FH : undef;
- }
-
-Although that will actually produce a small memory leak. See the bottom
-of L<perlfunc/open()> for a somewhat cleaner way using the FileHandle
-functions supplied with the POSIX package.
-
=head2 Prototypes
As of the 5.002 release of perl, if you declare
@@ -645,7 +662,7 @@ The interesting thing about & is that you can generate new syntax with it:
&$catch;
}
}
- sub catch (&) { @_ }
+ sub catch (&) { $_[0] }
try {
die "phooey";