390 likes | 506 Views
Programming Languages 2nd edition Tucker and Noonan. Chapter 12 Imperative Programming I really hate this darn machine; I wish they would sell it; It won’t do what I want it to, but only what I tell it. Programmer’s lament (anonymous). Contents. 12.1 What Makes a Language Imperative?
E N D
Programming Languages2nd editionTucker and Noonan Chapter 12 Imperative Programming I really hate this darn machine; I wish they would sell it; It won’t do what I want it to, but only what I tell it. Programmer’s lament (anonymous)
Contents 12.1 What Makes a Language Imperative? 12.2 Procedural Abstraction 12.3 Expressions and Assignment 12.4 Library Support for Data Structures 12.5 C 12.6 Ada 12.7 Perl
Perl is: • widely used • a scripting language (originally for Unix) • dynamically typed • encourages a variety of styles • supports regular expression pattern matching
“Larry Wall ... created Perl when he was trying to produce some reports from a Usenet-news-like hierarch of files for a bug reporting system, and awk ran out of steam. Larry, being the lazy programmer that he is, decided to over-kill the problem with a general purpose tool that he could use in at least one other place. The result was the first version of Perl.”
Scripting Languages • “glue” • take output from one application and reformat into desired input format for a different application. • most time is spent in the underlying applications. • also used for Web applications
General Characteristics • dynamically typed • default conversion from one type to another (vs. Python) • result is distinct operators; ex: . for string concatenation • types: numbers, strings, regular expressions • dynamic arrays: indexed and associative
String vs. numeric comparisons: • 10 < 2 # false - numeric • 10 < "2" # false • "10" lt "2" # true - string • 10 lt "2" # true
Indexed Arrays • @a = (2, 3, 5, 7); # size is 4 • ... • $a[7] = 17; # size is 8; • # $a[4:6] are undef
Associative Arrays • %d = (“bob” => “3465”, • “allen” => “3131”, • “rebecca” => “2912”); • print $d{“bob”}; # prints 3465
Many different ways of saying the same thing • Much of the syntax is optional; ex: ( ) • Perl 5 added support for classes and objects • Great strengths: support for regular expressions • Many irregularities in Perl
#! /usr/bin/perl • die "Usage mygrep string \n" if @ARGV < 1; • use strict; • my $string = shift; • my $ct = 0; • while (<>) { • $ct++; • print "$ct:\t$_" if /$string/; • } • exit;
Scalar variables start with a $ • Indexed arrays with an @ • Hash arrays with % • Otherwise: bare word syntax error
use strict forces declaration of variables • local : dynamic scoping • my : static scoping • NB: only 1 $_
Strings • Double quotes: special characters interpreted • ex: “$a \n” • forms: “ “, qq{ }, qq/ / • Single quotes: special characters uninterpreted • forms: ‘ ‘, q{ }, q/ /
while (<>) { ... } • is same as: • while ($_ = <STDIN>) { ... } • where: • <> is read a line • returns undef at end of file; undef interpreted as false • no subject: $_ • if $_ =~ m/pattern/ # implied subject, operator
#! /usr/bin/perl • if (@ARGV < 1) { die "Usage mygrep string \n" ; } • use strict; • my $string = shift(@ARGV); • my $ct = 0; • my $line; • while ($line = <STDIN>) { • $ct++; • if ($line =~ m/$string/) { • print STDOUT $ct, ":\t", $line; • } • } • exit;
Ex: Mailing Grades • typical glue program • student grades kept in a spreadsheet • after each project/test, mail each student her grades • include averages • export data in comma-separated value format (CSV) • CSV format varies by spreadsheet
Fig. 12.15 • ::Proj1:Test1:::::Total:Average • ::50:100::::::150: • Tucker:atuck@college.edu:48:97:::::145:96.66666666 • Noonan:rnoon@college.edu:40:85:::::125:83.33333333 • Average::88:91:::::135:90
Main program - part 1 • retrieves class designation from command line • opens CSV file for input • or die is a common idiom • declares some useful constants (some should be command line options)
#! /usr/bin/perl • use strict; • my $class = shift; • my $suf = ".csv"; • open(IN, "<$class$suf") || die "Cannot read: " . "$class$suf\n"; • my $sep = ":"; • my $tab = 8;
Main program - part 2 • reads grade column names • reads maximum points for each column • adds 100% to @max array
# read header lines: titles, max grades • my @hdr = &readSplit(); • my @max = &readSplit(); • push(@max, '100%');
Main program - part 3 • loop reads 1 student per iteration (line) • chomp() idiom; irregular • tr deletes “ , ' • tokenizer for Perl • last line pops averages from student array and splits values into columns (printed with each student)
# read students • my @student; • while (<IN>) { • chomp; • tr /"'//d; • push(@student, $_); • } • my @ave = split(/$sep/, pop(@student));
Main - part 4 • for loop generates mail, 1 student per iteration • student grades split into columns • subroutine call; & optional • mails averages to script invoker • prints number of student emails generated
# gen mail for each student • my $ct = 0; • foreach (@student) { • my @p = split(/$sep/); • $ct += &sendMail(@p); • } • $ave[1] = $ENV{"USER"}; • &sendMail(@ave); • print "Emails sent: $ct\n"; • exit;
sub readSplit • reads a line; note $_ is global • chomp idiom • tr deletes quotes • splits line and returns array of columns
sub readSplit { • $_ = <IN>; • chomp; • tr /"'//d; • my @r = split(/$sep/); • return @r; • }
sub sendMail • no formal parameters • shift -- call by value • @_ array reference -- call by reference • return if student has no email address • open pseudo file or die • MAIL is a pipe to Berkeley mail command • s option is subject • $email is mail address
sub sendMail { • my $name = shift; • my $email = shift; • return 0 unless $email; • open(MAIL, "| mail -s '$class Grades' $email") • || die "Cannot fork mail: $!\n"; • print MAIL "GRADE\t\tYOUR\tMAX\tCLASS\n", • "NAME\t\tSCORE\tSCORE\tAVE\n\n";
sub sendMail -- for loop • for each column • skip column if empty header -- not a grade • otherwise print header • if column value starts with a digit, round value to an integer; otherwise print value • { } required; reason for backwards if/unless • print maximum points • print average (rounded)
my $ct = 1; • foreach (@_) { • $ct++; • next unless $hdr[$ct]; • print MAIL "$hdr[$ct]\t"; • print MAIL "\t" if length($hdr[$ct]) < $tab; • if (/^\d/) { print MAIL int($_ + 0.5); } • else { print MAIL $_; }
print MAIL "\t$max[$ct]\t"; • if ($ave[$ct] =~ /^\d/) { • print MAIL int($ave[$ct] + 0.5); • } else { print MAIL $ave[$ct];} • print MAIL "\n"; • } # foreach • return 1; • } # sub sendMail
$_ : implied object/subject • $ARG : default input • $. : input line number • $/ : input record separator : default \n • undef $/; $_ = <IN>; # reads entire file • $, : output field separator in print • $\ : output record separator • $" : list separator : default space • $[ : starting array index : default zero • 10 pages of these; also names
Regular Expressions • Operators • m// -- match, m optional • s/// -- substitute • split -- array returning function
Modifiers • i -- case insensitive • m -- treat string as multiple lines • s -- treat string as a single line • x -- extend with whitespace and comments
Most characters match themselves • Meta characters: \ | ( ) [ { ^ $ * + ? . • ^ if first -- match from beginning of string • $ if last -- match until end of string • . -- single character wildcard • * + ? -- Kleene star • Questions • Empty string? • Entire string? • First x to end of string?
[ ] -- set • letters, digits, vowels • [^ ] -- not in set • | -- or • ( ) -- grouping • predefined sets (lc) and their inverses (uc) • \d : digits • \w : letters plus digits • \s : whitespace