ignored. If you attempt to use C</* */> C-style comments, it will be
interpreted either as division or pattern matching, depending on the
context, and C++ C<//> comments just look like a null regular
-expression, so don't do that.
+expression or defined-or operator, so don't do that.
=head2 Declarations
C<"">; and when used as a reference that isn't being assigned
to, it is treated as an error. If you enable warnings, you'll
be notified of an uninitialized value whenever you treat C<undef>
-as a string or a number. Well, usually. Boolean ("don't-care")
-contexts and operators such as C<++>, C<-->, C<+=>, C<-=>, and
-C<.=> are always exempt from such warnings.
+as a string or a number. Well, usually. Boolean contexts, such as:
+
+ my $a;
+ if ($a) {}
+
+are exempt from warnings (because they care about truth rather than
+definedness). Operators such as C<++>, C<-->, C<+=>,
+C<-=>, and C<.=>, that operate on undefined left values such as:
+
+ my $a;
+ $a++;
+
+are also always exempt from such warnings.
A declaration can be put anywhere a statement can, but has no effect on
the execution of the primary sequence of statements--declarations all
sub myname;
$me = myname $0 or die "can't get myname";
-Note that my() functions as a list operator, not as a unary operator; so
-be careful to use C<or> instead of C<||> in this case. However, if
+Note that myname() functions as a list operator, not as a unary operator;
+so be careful to use C<or> instead of C<||> in this case. However, if
you were to declare the subroutine as C<sub myname ($)>, then
C<myname> would function as a unary operator, so either C<or> or
C<||> would work.
statements as if it were an ordinary statement. That means it actually
has both compile-time and run-time effects.
-=head2 Simple statements
+=head2 Simple Statements
The only kind of simple statement is an expression evaluated for its
side effects. Every simple statement must be terminated with a
} while $x++ <= $z;
}
-=head2 Compound statements
+B<NOTE:> The behaviour of a C<my> statement modified with a statement
+modifier conditional or loop construct (e.g. C<my $x if ...>) is
+B<undefined>. The value of the C<my> variable may be C<undef>, any
+previously assigned value, or possibly anything else. Don't rely on
+it. Future versions of perl might do something different from the
+version of perl you try it out on. Here be dragons.
+
+=head2 Compound Statements
In Perl, a sequence of statements that defines a scope is called a block.
Sometimes a block is delimited by the file containing it (in the case
refers to the innermost enclosing loop. This may include dynamically
looking back your call-stack at run time to find the LABEL. Such
desperate behavior triggers a warning if you use the C<use warnings>
-praga or the B<-w> flag.
-Unlike a C<foreach> statement, a C<while> statement never implicitly
-localises any variables.
+pragma or the B<-w> flag.
If there is a C<continue> BLOCK, it is always executed just before the
-conditional is about to be evaluated again, just like the third part of a
-C<for> loop in C. Thus it can be used to increment a loop variable, even
-when the loop has been continued via the C<next> statement (which is
-similar to the C C<continue> statement).
+conditional is about to be evaluated again. Thus it can be used to
+increment a loop variable, even when the loop has been continued via
+the C<next> statement.
=head2 Loop Control
-The C<next> command is like the C<continue> statement in C; it starts
-the next iteration of the loop:
+The C<next> command starts the next iteration of the loop:
LINE: while (<STDIN>) {
next LINE if /^#/; # discard comments
...
}
-The C<last> command is like the C<break> statement in C (as used in
-loops); it immediately exits the loop in question. The
+The C<last> command immediately exits the loop in question. The
C<continue> block, if any, is not executed:
LINE: while (<STDIN>) {
# now process $line
}
-Note that if there were a C<continue> block on the above code, it would get
-executed even on discarded lines. This is often used to reset line counters
-or C<?pat?> one-time matches.
+Note that if there were a C<continue> block on the above code, it would
+get executed only on lines discarded by the regex (since redo skips the
+continue block). A continue block is often used to reset line counters
+or C<?pat?> one-time matches:
# inspired by :1,$g/fred/s//WILMA/
while (<>) {
they aren't loops. You can double the braces to make them such, though.
if (/pattern/) {{
- next if /fred/;
- next if /barney/;
- # so something here
+ last if /fred/;
+ next if /barney/; # same effect as "last", but doesn't document as well
+ # do something here
}}
+This is caused by the fact that a block by itself acts as a loop that
+executes once, see L<"Basic BLOCKs and Switch Statements">.
+
The form C<while/if BLOCK BLOCK>, available in Perl 4, is no longer
available. Replace any occurrence of C<if BLOCK> by C<if (do BLOCK)>.
=head2 For Loops
-Perl's C-style C<for> loop works exactly like the corresponding C<while> loop;
+Perl's C-style C<for> loop works like the corresponding C<while> loop;
that means that this:
for ($i = 1; $i < 10; $i++) {
$i++;
}
-(There is one minor difference: The first form implies a lexical scope
-for variables declared with C<my> in the initialization expression.)
+There is one minor difference: if variables are declared with C<my>
+in the initialization section of the C<for>, the lexical scope of
+those variables is exactly the C<for> loop (the body of the loop
+and the control sections).
Besides the normal array index looping, C<for> can lend itself
to many other interesting applications. Here's one that avoids the
# do something
}
+Using C<readline> (or the operator form, C<< <EXPR> >>) as the
+conditional of a C<for> loop is shorthand for the following. This
+behaviour is the same as a C<while> loop conditional.
+
+ for ( prompt(); defined( $_ = <STDIN> ); prompt() ) {
+ # do something
+ }
+
=head2 Foreach Loops
The C<foreach> loop iterates over a normal list value and sets the
implicitly local to the loop and regains its former value upon exiting
the loop. If the variable was previously declared with C<my>, it uses
that variable instead of the global one, but it's still localized to
-the loop.
+the loop. This implicit localisation occurs I<only> in a C<foreach>
+loop.
The C<foreach> keyword is actually a synonym for the C<for> keyword, so
you can use C<foreach> for readability or C<for> for brevity. (Or because
the Bourne shell is more familiar to you than I<csh>, so writing C<for>
comes more naturally.) If VAR is omitted, C<$_> is set to each value.
-If any element of LIST is an lvalue, you can modify it by modifying VAR
-inside the loop. That's because the C<foreach> loop index variable is
-an implicit alias for each item in the list that you're looping over.
+
+If any element of LIST is an lvalue, you can modify it by modifying
+VAR inside the loop. Conversely, if any element of LIST is NOT an
+lvalue, any attempt to modify that element will fail. In other words,
+the C<foreach> loop index variable is an implicit alias for each item
+in the list that you're looping over.
If any part of LIST is an array, C<foreach> will get very confused if
you add or remove elements within the loop body, for example with
}
There is no official C<switch> statement in Perl, because there are
-already several ways to write the equivalent. In addition to the
-above, you could write
+already several ways to write the equivalent.
+
+However, starting from Perl 5.8 to get switch and case one can use
+the Switch extension and say:
+
+ use Switch;
+
+after which one has switch and case. It is not as fast as it could be
+because it's not really part of the language (it's done using source
+filters) but it is available, and it's very flexible.
+
+In addition to the above BLOCK construct, you could write
SWITCH: {
$abc = 1, last SWITCH if /^abc/;
}
(That's actually not as strange as it looks once you realize that you can
-use loop control "operators" within an expression, That's just the normal
-C comma operator.)
+use loop control "operators" within an expression. That's just the binary
+comma operator in scalar context. See L<perlop/"Comma Operator">.)
or
"read-only";
};
-Or if you are certainly that all the C<&&> clauses are true, you can use
+Or if you are certain that all the C<&&> clauses are true, you can use
something like this, which "switches" on the value of the
-C<HTTP_USER_AGENT> envariable.
+C<HTTP_USER_AGENT> environment variable.
#!/usr/bin/perl
# pick out jargon file page based on browser
=head2 Plain Old Comments (Not!)
-Much like the C preprocessor, Perl can process line directives. Using
+Perl can process line directives, much like the C preprocessor. Using
this, one can control Perl's idea of filenames and line numbers in
error or warning messages (especially for strings that are processed
with C<eval()>). The syntax for this mechanism is the same as for most
C preprocessors: it matches the regular expression
-C</^#\s*line\s+(\d+)\s*(?:\s"([^"]+)")?\s*$/> with C<$1> being the line
-number for the next line, and C<$2> being the optional filename
-(specified within quotes).
+
+ # example: '# line 42 "new_filename.plx"'
+ /^# \s*
+ line \s+ (\d+) \s*
+ (?:\s"([^"]+)")? \s*
+ $/x
+
+with C<$1> being the line number for the next line, and C<$2> being
+the optional filename (specified within quotes).
+
+There is a fairly obvious gotcha included with the line directive:
+Debuggers and profilers will only show the last source line to appear
+at a particular line number in a given file. Care should be taken not
+to cause line number collisions in code you'd like to debug later.
Here are some examples that you should be able to type into your command
shell: