CS 105 Perl: Basic I/O, Context, Strings, Lists Nathan Clement January 22, 2014

Download Report

Transcript CS 105 Perl: Basic I/O, Context, Strings, Lists Nathan Clement January 22, 2014

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.
Operator
Numeric
Stringwise
Less than
<
lt
Less than or equal to
<=
le
Equal to
==
eq
Greater than
>
gt
Greater than or equal to
>=
ge
Not equal
!=
ne
Basic Input/Output
One way to read lines from standard input:
while (defined($a = <STDIN>)) {
Removes line terminator
chomp($a);
# do something with $a
}
STDIN is the built-in filehandle for 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.
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, undef becomes the empty
string.
In a numeric context, undef becomes 0.
In a boolean context, undef needs 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 foreach over 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, foreach and 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 and when
Perl 5.10 finally introduces a switch/case
mechanic into Perl. given plays the part of
switch, and when plays the part of case.
use feature qw(switch);
given ($grade)
when (’A’) {
when (’B’) {
when (’C’) {
# ...
}
{
print "Excellent\n"; }
print "Good job\n"; }
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 when clauses
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
default last.
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.