4.5. Bare BlocksA BLOCK by itself (labeled or not) is semantically equivalent to a loop that executes once. Thus you can use last to leave the block or redo to restart the block.[4] Note that this is not true of the blocks in eval {}, sub {}, or, much to everyone's surprise, do {}. These three are not loop blocks because they're not BLOCKs by themselves; the keyword in front makes them mere terms in an expression that just happen to include a code block. Since they're not loop blocks, they cannot be given a label to apply loop controls to. Loop controls may only be used on true loops, just as a return may only be used within a subroutine (well, or an eval).
Loop controls don't work in an if or unless, either, since those aren't loops. But you can always introduce an extra set of braces to give yourself a bare block, which does count as a loop:
Here's how a block can be used to let loop-control operators work with a do{} construct. To next or redo a do, put a bare block inside:
For last, you have to be more elaborate:
And if you want both loop controls available, you'll have put a label
on those blocks so you can tell them apart:
But certainly by that point (if not before), you'd be better off using
an ordinary infinite loop with last at the end:
4.5.1. Case StructuresUnlike some other programming languages, Perl has no official switch or case statement. That's because Perl doesn't need one, having many ways to do the same thing. A bare block is particularly convenient for doing case structures (multiway switches). Here's one:
and here's another:
or, formatted so that each case stands out more:
or even (horrors!):
In this next example, notice how the last operators ignore the do
{} blocks, which aren't loops, and exit the for loop instead:
You might think it odd to loop over a single value, since you'll only
go through the loop once. But it's convenient to use for/foreach's
aliasing capability to make a temporary, localized assignment to
$_. On repeated compares against the same long value, this makes it
much easier to type and therefore harder to mistype. It avoids
possible side effects from evaluating the expression again. And
pertinent to this section, it's also one of the most commonly seen
standard idioms for implementing a switch or case structure.
Cascading use of the ?: operator can also work for simple cases. Here we again use a for for its aliasing property to make repeated comparisons more legible:
For situations like this last one, it's sometimes better to build
yourself a hash and quickly index into it to pull the answer out.
Unlike the cascading conditionals we just looked at, a hash scales to
an unlimited number of entries, and takes no more time to look up the
first one than the last. The disadvantage is that you can only do an
exact lookup, not a pattern match. If you have a hash like this:
then exact string lookups run quickly:
Even complicated multiway branching statements (with each case
involving the execution of several different statements) can be turned
into fast lookups. You just need to use a hash of references to
functions. See the section Section 4.5, "Hashes of Functions" in Chapter 9, "Data Structures", for how to handle those.
![]() Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|