more perl control flow software tools. slide 2 control flow l we have already seen several perl...

31
More Perl Control Flow Software Tools

Upload: dakota-hodnett

Post on 15-Dec-2015

221 views

Category:

Documents


0 download

TRANSCRIPT

More Perl Control Flow

Software Tools

Slide 2

Control Flow We have already seen several Perl

control flow statements: if while for last

Other control flow statements: unless until do while do until foreach next redo

Slide 3

unless The Perl unless statement is like an if statement

with the condition negated:

if($temperature <= 20){print "too cold!\n";

}

unless($temperature > 20){ # same thingprint "too cold!\n";

}-------------------------------------------if(!$hot){

print "too cold!\n";}

unless($hot){ # same thingprint "too cold!\n";

}

Slide 4

unless unless can have else, just like if:

#!/usr/local/bin/perl5 -w

print "Enter temperature: ";

chomp($temperature = <STDIN>);

unless($temperature > 20){

print "too cold!\n";

}else{

print "too hot!\n";

}

Slide 5

unless unless can also have elsif, just like if:

#!/usr/local/bin/perl5 -w

print "Enter temperature: ";

chomp($temperature = <STDIN>);

unless($temperature >= 20){

print "too cold!\n";

}elsif($temperature == 20){

print "ok!\n";

}else{

print "too hot!\n";

}

Slide 6

until The Perl until statement is like a while

statement with the condition negated. Sometimes is is easier to say “until something is

true” rather than “while not this is true”:

while(!$endoffile){...

}

until($endoffile){ # same thing...

}

Slide 7

until The until statement loops indefinitely, until the

condition is true, such as a user-controlled condition:

#!/usr/local/bin/perl5 -w$resp = "no";

until($resp eq "yes"){print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);

}$ test11Wakeup [yes/no]? noWakeup [yes/no]? yWakeup [yes/no]? yes$

Slide 8

do while The do while statement is like the C++ do while

statement. It loops indefinitely, while the condition is true, such

as a user-controlled condition: do while always executes the body of the loop at

least once. #!/usr/local/bin/perl5 -w

do{print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);

}while($resp ne "yes");$ test11Wakeup [yes/no]? noWakeup [yes/no]? yes$

Slide 9

do until The do until statement loops indefinitely, until

the condition is true, such as a user-controlled condition.

do until always executes the body of the loop at least once.

#!/usr/local/bin/perl5 -w do{

print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);

}until($resp eq "yes");$ test11Wakeup [yes/no]? noWakeup [yes/no]? yWakeup [yes/no]? yes$

Slide 10

foreach

foreach takes a list of values and assigns them one by one to a scalar variable.

The body of the loop is executed once for each successive assignment.

foreach is similar to the shell programming’s for statement.

foreach $i (@some_list){...

}

Slide 11

foreach The following example sums the contents of an

array:

$ cat sum#!/usr/local/bin/perl5 -w@a = (21,32,3,44,75,16,19);$sum = 0;foreach $b (@a){

$sum += $b;}print "The array sum is: $sum\n";$ sumThe array sum is: 210 $

Slide 12

foreach foreach allows us to easily print an array in our

own customized way. The following example prints an array with each

element separated by 2 spaces:

$ cat print1#!/usr/local/bin/perl5 -w@a = (1,2,3,4,5);foreach $i (@a){

print "$i ";}print "\n";$ print11 2 3 4 5 $

Slide 13

foreach The following example prints the numbers in reverse

order without changing the array:

$ cat print2#!/usr/local/bin/perl5 -w@a = (1,2,3,4,5);foreach $i (reverse @a){

print "$i ";}print "\n";$ print25 4 3 2 1 $

reverse @a is the same as writing reverse(@a). Parenthesis are always optional on Perl functions.

Slide 14

foreach $_ If you omit the scalar variable in foreach, Perl will

use $_ automatically:

$ cat print3#!/usr/local/bin/perl5 -w@a = (1,2,3,4,5);foreach (reverse @a){

print;}print "\n";$ print354321 $

print (and other Perl functions) use $_ as the default if nothing is specified.

Slide 15

foreach $_ Of course, if you want double spaces, you will

have to use $_ explicitly:

$ cat print3a#!/usr/local/bin/perl5 -w@a = (1,2,3,4,5);foreach (reverse @a){

print "$_ ";}print "\n";$ print3a5 4 3 2 1$

Slide 16

foreach The scalar variable in foreach is an alias for each

variable in the list, not just a copy. (Tricky!) If you modify the scalar variable in foreach, the

aliased element in the list is also changed:$ cat double#!/usr/local/bin/perl5 -w@a = (1,2,3,4);foreach $b (@a){

$b *= 2;}print "@a\n";$ double2 4 6 8 $

Slide 17

last Again The last command only breaks out of while, until, for, and foreach loops.

For mysterious reasons, do while and do until do not count as loops in Perl.

$ cat last1#!/usr/local/bin/perl5 -w

do{print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

last;}

}while(1);$ last1Wakeup [yes/no]? yesCan't "last" outside a block at last1 line 6, <STDIN> chunk 1.$

Slide 18

last Again In the example below, the last statement causes the outer while loop to be broken:

$ cat last2#!/usr/local/bin/perl5 -w

while(1){do{

print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

last;}

}while(1);}$ last2Wakeup [yes/no]? yes$

Slide 19

next The next command causes a jump to the end of the

loop, but without terminating the loop.$ cat next1#!/usr/local/bin/perl5 -w$resp = "no";until($resp eq "quit" || $resp eq "yes"){

print "Wakeup [yes/no/quit]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

next;}print "sleeping...\n";

}$ next1Wakeup [yes/no/quit]? nosleeping...Wakeup [yes/no/quit]? yes$ next1Wakeup [yes/no/quit]? quitsleeping...$

Slide 20

redo The redo command causes a jump back to the

beginning of the loop, but without re-testing the condition (next re-tests the condition).

$ cat redo#!/usr/local/bin/perl5 -w$resp = "no";until($resp eq "quit" || $resp eq "yes"){

print "Wakeup [yes/no/quit]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

redo;}print "sleeping...\n";

}$ redoWakeup [yes/no/quit]? nosleeping...Wakeup [yes/no/quit]? yesWakeup [yes/no/quit]? quitsleeping...$

Slide 21

next and redo Like last, next and redo only break out of while, until, for, and foreach loops (not do while and do until loops).

$ cat redo1#!/usr/local/bin/perl5 -w$resp = "no";do{

print "Wakeup [yes/no/quit]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

redo;}print "sleeping...\n";

}until($resp eq "quit" || $resp eq "yes");$ redo1Wakeup [yes/no/quit]? nosleeping...Wakeup [yes/no/quit]? yesCan't "redo" outside a block at redo1 line 7, <STDIN> chunk 2.$

Slide 22

redo and last/next You can make a while loop using redo and last/next in a “naked” block (a “naked” block is a block { } that is not part of a loop or if statement):

$ cat redo2#!/usr/local/bin/perl5 -w{

print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);if($resp eq "yes"){

last; # could also use "next;"}redo;

}$ redo2Wakeup [yes/no]? noWakeup [yes/no]? yWakeup [yes/no]? yes$

Slide 23

Labeled Blocks What if you want to jump out of two nested loops? In C++, you’d be in trouble. In Perl, you can use labeled loops to break out of an

outer loop using last, next, and redo. For clarity (and other reasons), it is best to choose label

names that are all upper case letters and digits. Labels always end in a colon “:”.

OUTERLOOP: for($i=1; $i<3; $i++){INNERLOOP: for($j=1; $j<5; $j++){

...

Add the label (without the colon) as a parameter to last, for example, if you want to exit OUTERLOOP.

last OUTERLOOP;

Slide 24

Labeled Blocks Example

$ cat label#!/usr/local/bin/perl5 -w$sum = 0;LOOP1: for($i1=1; $i1<=2; $i1++){

LOOP2: for($i2=1; $i2<=2; $i2++){LOOP3: for($i3=1; $i3<=2; $i3++){

$sum += 1;print "sum so far: $sum\n";if($sum > 2){

last LOOP2; }

}$sum += 2;

}$sum += 3;

}print "sum at end: $sum\n";$ labelsum so far: 1sum so far: 2sum so far: 5sum so far: 9sum at end: 12$

Slide 25

Backward if A simple way to write “if this, then that” is:

chomp($user = `whoami`);print("Hi Bill!\n") if($user eq "gates");

is the same as:

chomp($user = `whoami`);if($user eq "gates"){

print "Hi Bill!\n";}

Backward if avoids having to write the curly braces { }.

There can only be one statement inside the block.

Slide 26

Backward if Backward if is a natural and tidy way to exit from

a loop:

$ cat backif#!/usr/local/bin/perl5 -w

while(1){print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);last if $resp eq "yes";

};$ backifWakeup [yes/no]? noWakeup [yes/no]? yWakeup [yes/no]? yes$

Slide 27

Backward unless, while, until

You can also use backward unless, while, and until (if there is only one statement in the block):

$ cat sum#!/usr/local/bin/perl5 -wprint "Enter numbers to sum (0 to quit): \n";$sum = 0;$n = 1;$sum += $n = <STDIN> while($n != 0);print "The sum is: $sum: \n";$ sumEnter numbers to sum (0 to quit): 110The sum is: 2$

Slide 28

&& if Another simple way to write “if this, then that” is:

chomp($user = `whoami`);$user eq "gates" && print("Hi Bill!\n");

is the same as:

chomp($user = `whoami`);if($user eq "gates"){

print("Hi Bill!\n");}

Slide 29

&& if

this && that;

Why does this work? Isn’t && the logical-and operator? Consider what happens when this and that take on values of true and false: If this is true, then the value of the entire expression

is still not known, because it depends on the value of that. So that has to be evaluated.

If this is false, there is no need to look at that, because the value of the whole expression must be false. Since there is no need to evaluate that, Perl skips it.

Slide 30

&& if && if is also a tidy way to exit from a loop:

$ cat backif1#!/usr/local/bin/perl5 -w

while(1){print "Wakeup [yes/no]? ";chomp($resp = <STDIN>);$resp eq "yes" && last;

};$ backif1Wakeup [yes/no]? noWakeup [yes/no]? yWakeup [yes/no]? yes$

Slide 31

|| unless Similarly, another simple way to write an unless

statement is:

$temperature > 20 || print "too cold!\n";

is the same as:

unless($temperature > 20){ # same thingprint "too cold!\n";

}