320 likes | 401 Vues
CS 105 Perl: Basic I/O, Context, Strings, Lists. Nathan Clement January 22, 2014. Agenda. Today we will cover Basic I/O Context String literals and quoting Lists Intermediate iteration foreach Array iteration Hash iteration given / when. Survey Results. Languages Known
E N D
CS 105 Perl:Basic I/O, Context, Strings, Lists Nathan Clement January 22, 2014
Agenda Today we will cover • Basic I/O • Context • String literals and quoting • Lists • Intermediate iteration • foreach • Array iteration • Hash iteration • given / when
Survey Results • Languages Known • “C – I know some, I’ll use it if I want total control.” • Workload • “Should be easy.” • “It’s like a 3 hour class for 1 hour of credit.” • “The workload will be more intense as the semester progresses but overall the class will be a good experience.”
if with else if ($rich) { print "I am the 1\%\n"; } elsif ($poor) { print "I’m economically disadvantaged\n";} else { print "I’m disappearing!!\n";} How to handle the age-old “Dangling Else” problem
while loop A simple while loop (review): while ($a > 0) { print $a." bottles of beer.\n"; $a--;} Do any questions come to mind?
Numeric vs. Stringwise Comparisons Perl has two sets of operators depending on if you want to compare two scalars numerically or as strings.
Basic Input/Output One way to read lines from standard input: while (defined($a = <STDIN>)) { chomp($a); # do something with $a } STDIN is the built-in filehandlefor standard input. Placing a filehandle in the angle brackets (< >) tells Perl to return the next line from that file. When the end-of-file is reached, <STDIN> will return undef. Removes line terminator
Our own wc–l Increment a value for each line read from STDIN. while (defined($a = <STDIN>)) { $b++;}print $b . "\n";
Context Perl has several contexts that affect how a value is used. • Scalar • Numeric • String • Boolean • don’t care • List • Void • Interpolative Perl will perform a default conversion, if necessary, of a value into the desired context. Context only affects evaluation; it does not change the values stored in variables.
Numeric Context A numeric operation wants a number, so the value is evaluated in numeric context. $b = "10"; $a += $b; We initialized $b as a string, but Perl will automatically convert it to a number because the + operator forces a numeric context. Perl will even convert numbers into integers (by rounding) if the specific operation requires an integer (e.g. modulus, %)
String Context Similarly, a string operation wants a string, so its inputs have string context. $a = "Fingers: "; $b = 10; $a .= $b; We initialized $b as a number, but Perl will transparently convert it into a string because the . operator forces a string context. Remember, the numeric value stored in $b does not change.
undef awakening In a string context, undefbecomes the empty string. In a numeric context, undefbecomes 0. In a boolean context, undefneeds no conversion: it’s already considered false. In fact, boolean context will never convert anything, since it applies to numbers, strings, lists, and undefined values.
String Literals Recall from earlier this lecture: print $a . " bottles of beer on the wall.\n";# we could have done this:print "$a bottles of beer on the wall.\n";# the result is the same Values placed in a double-quoted string are evaluated in interpolative context.
Interpolation interpolate, v.1. to introduce (something additional or extraneous) between other things or parts; interject; interpose; intercalate. Basic interpolation rules: • scalar values are evaluated in string context • escape them with \ to prevent this • escape sequences can be used for control characters • \n for newline • \r for carriage return • \t for (horizontal) tab • there are many others
Single quotes Don’t want interpolation? Use single quotes. if ($a) { print '$a is true', "\n";} Single quotes do not interpolate variables or escape sequences. We could escape the $ with a backslash. if ($a) { print "\$a is true\n";}
Perl style: use interpolation! Recall from earlier this lecture: print $a . " bottles of beer.\n";# What a newbie...print "$a bottles of beer.\n";# Much better! Please write your code as in the second example.
Lists Lists allow us to initialize arrays and hashes. @a = (1, 2, 3, 4);@b = ('a', 'b', 'c', 'd');
Lists save typing Lists are much better than initializing each element individually. @a = (1, 2, 3, 4); is equivalent to undef @a; $a[0] = 1; $a[1] = 2; $a[2] = 3; $a[3] = 4;
Lists and Hashes Lists can also be used to initialize hashes. %a = ('a', 1, 'b', 2); is equivalent to undef %a; $a{'a'} = 1; $a{'b'} = 2;
The fat arrow: => The => operator is like a comma in almost every way... %a = (a => 1, b => 2); except that the argument to its left will be treated as a string if it is a bareword. A bareword is an identifier without a sigil. So far, only keywords and some operators (eq, etc.) are allowed to be used without quotes or sigils. In this example, a and b are barewords but are evaluated as strings because of the => operator. The end result is the same as the previous slide.
Perl style: use the fat arrow! The proper, idiomatic thing to do in Perl is to use => when the two delimited elements are pairs. It can be used anywhere a comma could be used. I only gave the previous example with commas to drive home the point that commas are the standard (not fancy) separator. Fat arrow is a fancy comma.
Barewords in hash keys The same bareword-to-string promotion also happens inside the curly braces of a hash key. $a{a} = 1; $a{b} = 2;
Hashes are unordered Remember: hashes are unordered. The following two lines are equivalent: %a = (a => 1, b => 2); %a = (b => 2, a => 1);
foreach iteration You will iterate over arrays a lot in Perl. For general loops over arrays, use foreach. foreach is intended to be dwimmy. For example: foreach $foo (@foo) { $foo .= $foo; } You would read this as “for each foo in array foo ...”
foreach iteration over hashes You can also use foreach, to iterate over hashes. For general loops over hashes, use foreachover the keys of the hash. foreach$foo (keys %foo) { $foo{$foo} .= $foo; } You would read this as “for each foo that is a key in hash foo ...”
foreach iteration over hash values While considerably less common or useful, you can also look at just the values in a hash. foreach $bar (values %foo) { print "$bar\n"; } This reads “for each bar that is a value in hash foo ...”
foreach vs. for Perl also has a for loop with syntax similar to C and Java. It will not be covered in this class since you should already be an expert in its use.
foreach, for, whatever Actually, foreachand for are synonyms. Perl can figure out which type of loop you mean, so the two keywords are interchangeable. Using the for keyword for “foreach-style” loops is okay. for $baz (@baz) { # ...}
given andwhen Perl 5.10 finally introduces a switch/case mechanic into Perl. givenplays the part of switch, and when plays the part of case. use feature qw(switch);given ($grade) { when (’A’) { print "Excellent\n"; } when (’B’) { print "Good job\n"; } when (’C’) { print "Be all that you can be\n"; } # ...}
given/when is ‘smart’ If the when expression is a string, Perl will automatically do a string comparison (eq). If it’s a number, Perl will automatically do a numeric comparison (==). @a = (’0’, ’00’, 0);foreach$a (@a) { given ($a) { when (’0’) { print "String-wise equal to ’0’\n"; } when (0) { print "Numerically equal to 0\n"; } }} Perl tests each when clause in turn; the first to match gets executed, even if multiple tests would match. Try changing the order in the example.
The default clause If you would like a default behavior if none of the whenclauses match, then use the default clause. given ($grade) { when (’A’) { print "Excellent\n"; } default { print "Too bad...\n"; }} Remember that the clauses are tested in order, so always put defaultlast.
Enabling features As the previous examples have shown, a little bit of effort is required to enable given/when. # loads all Perl 5.10 features# (also includes say, smart match, and more)use feature ’:5.10’; Alternatively, you can just require a version of Perl >= 5.10.0, and the feature pragma will be loaded implicitly. use v5.10;# implicitly does:# use feature ’:5.10’; I prefer this method over the others.