<<

COMS 3101 Programming Languages:

Lecture 6

Fall 2013 Instructor: Ilia Vovsha http://www.cs.columbia.edu/~vovsha/coms3101/perl Lecture Outline

ƒ Concepts: ƒ references ƒ Symbolic references ƒ Saving structures ƒ OOP (inheritance) ƒ More on modules: ƒ CPAN ƒ Prgamas: fields, base ƒ Module: Class::Struct ƒ Pod () ƒ Common remarks

6.2 Concepts

ƒ Subroutine references ƒ Copying referent ƒ Symbolic references ƒ Saving structures

6.3 Subroutine References

ƒ Reference to a sub follows similar rules ƒ Can use backslash or anonymous sub max { …. }# Anonymous $sub_ ref = \&max; $sub_ ref = sub { …. };

# Calling subroutine &$sub_ref(); $subfb_ref ‐> (); $sub_ref ‐> (1,4,6,8);

# Call sub using string my %cmds = ( “process” => \&process_data, “clear” => \&clear_data, “any” => sub {….} ); $cmds{$str} ‐> ();

6.4 Copy Referent

ƒ To copy referent for another reference:

$aref1 = [ 1,2,3 ]; $aref2 = [ 4,5,6 ];

$aref2 = $aref1 # Not a copy! Rather refers to the same location!

$aref2 = [ @$aref1 ];# Create a new anonymous reference $href2 = { %{$href1 } }; # Same approach for hashes

6.5 Symbolic References

ƒ Refers to the name of a variable ƒ If we try to dereference, we get access to variable! ƒ Can be dangerous! (use strict ‘refs’ to prohibit)

$N = “V”; $$N = 5; # Set scalar $V = 5 $N ‐> [0] = 6; # Set element 0 of array V to 6 $N ‐> {key} = 7; # Set key of hash V to 7 &$N; # Call sub V

6.6 Saving Data Structures

ƒ Save any DS to use later: Data::Dumper module ƒ Turn DS into a string, save externally to a file, read in the file and recover DS with / do ƒ CPAN module Storable: more efficient, but cannot be shared across different architectures use Data::Dumper; open (OUTFILE, “> filename”); print OUTFILE Data::Dumper‐>Dump([\%hash], [‘*hash’]); open (INFILE, “< filename”); undef $/; # undef record separator, read entire file eval ; # recreate %hash

use Storable; store(\%hash, “filename”); $href = retrieve(“filename”); %hash = % { retrieve(“filename”) } ;

6.7 OOP (inheritance)

ƒ We can define a hierarchy of classes to share methods between them ƒ Deridived / sub class ihinher its methhdods from base / parent / super class ƒ The super‐classes are specified in the @ISA array (declared with our) of the derived class. Each element of the array is a package (class) name ƒ Single Inheritance: one parent class (search parent for methods) ƒ Multiple Inheritance: multiple parent classes (search left‐to‐right through @ISA array, depth‐first order) ƒ Once method is found, store in cache for efficiency ƒ If @ISA is changed, the cache is invalidated (avoid it if you can!) ƒ Constructor Inheritance: no automatic call to base class constructor

6.8 OOP (method search)

ƒ If method not defined in class: search @ISA at runtime when a call is made ƒ ShSearch order given multip le parent classes: lftleft‐to‐rihtight throug h @ISA array, depth‐first

# Nissan.pm package Nissan; our @ISA = (Car, Truck);

# Call: Nissan‐>new()‐>build(“sedan”); # Search order: 1. Check if method (build) is defined in class (Nissan) 2. Check if method is defined in “$Nissan:: ISA[0]” (Car class) 3. Check if method is defined in @Car::ISA (Car’ @ISA array) 4. When done with ISA[0], repeat steps 2,3, for ISA[1] (Truck class)

6.9 Scoped Variables

ƒ my • creates private variable visible only within • hidden from outside of enclosing scope, and hides previously declared variables with identical name • confines name & value to scope • suitable for scalar/array/hash variables ƒ our • confines name only to scope (no effect on visibility) • suitable for scalar/array/hash variables • used to access global variables, their initial value inside block unchanged • effects or assignment persist after the scope of declaration (block) ƒ local • confines value only to scope • suitable for scalar/array/hash + more variables • initial value for variable is () or undef • value of variable is restored no matter how you exit the block (changes thrown away) • “dynamic” scope: value of variable depends on scope & changes during run‐time • ‘my’ is preferable over ‘local’

APP Scoped Variables (example)

$office = "global"; # Global $office &say(); # prints "global" &barney(); # prints "barney global", lexical scope; &fred(); # prints "fred fred", dynamic scope, &say(); # prints "global", restored after &fred() sub say { print "$office\n"; } # print the $office sub barney { my $office = "barney"; print "$office "; &say(); } sub fred { local $office = "fred"; print "$office "; &say(); }

APP CPAN

ƒ Comprehensive Perl Archive Network: repository for modules ƒ Installing a module: # Download the .gz file from CPAN, unzip and go to proper directory # Build: perl MakeFile.pl make test # Install: make install ƒ Alternative: install cpanm module App::cpanminus # Install cpanm cpanm Module::Name # get, unpack, build, and install modules

6.12 Method invocation (indirect)

ƒ Direct approach: arrow operator … INVOCANT‐>METHOD() ƒ IdiIndirec t approach: can be ambiguous … METHOD INVOCANT ARGS

$mazda = Car ‐> new(); # Class: Car, Method: new, Object: $mazda $mazda ‐> drive(“slow”); # Instance: $mazda, Method: drive

$mazda = new Car; # Same as above drive $mazda “slow”;

6.13 Pseudohashes (deprecated!)

ƒ Pseudohash: reference to array whose 1st element is reference to hash ƒ Purpose: can be tttdreated as array ref or hhhash ref ƒ Deprecated: slower, muddling, problems with multiple inheritance ƒ Alternatives: restricted hashes (Hash::Util)

$ph_ref = [ {maker => 1, color => 2}, “mazda”, “red” ]; # Definition $ph_ref‐>{color}; # Access element (href) $ph_ ref‐>[2]; # Access element (aref)

$ph_ref‐>[0]{cost} = 3; # Add element $ph_ref‐>[3] = “cheap”;

6.14 fields pragma

ƒ “Experimental” feature, enables compile‐time type‐verified class fields ƒ NtNote: pseudhdohas hes removed from perl 5105.10 ƒ The related base pragma provides for field inheritance from parent class ƒ fields::new() creates and blesses a pseudohash comprised of the fields declared using the fields pragma into the specified class.

package Car; package Car; use fields qw(maker color cost); sub new { my $class = shift; sub new { my $self = { my $class = shift; maker => “mazda”, my $self = fields::new($class); color => “red”, cost => “” $self‐>{maker} = “mazda”; }; $self‐>{color} = “red”; bless ($self, $class); return $self; return $self; } }

6.15 fields pragma (example)

ƒ Prevents typos in field names (otherwise accepted):

package Car; use fields qw(maker color cost);

sub new { my $class = shift; my $self = fields::new($class); $self‐>{{}maker} = “mazda”; $self‐>{color} = “red”; return $self; } sub some_fun { my $self = shift; $self‐>{colour} = “blue”; # throws error! }

6.16 base pragma

ƒ Simplifies inheritance in two ways: ƒ Assigns to @ISA without having to declare “our @ISA” ƒ Inherits fields of parent class if ‘fields’ pragma is used ƒ Problem: multiple inheritance is not supported! (raises exception if more than one base class uses ‘fields’ ) package Mazda; use base qw(Car); # Mazda is subclass of Car use fields qw(vehicle mpg); # Inherits fields from Car class, adds two new fields sub new { my $class = shift; my $lf$self = fldfields::new ($l($class ); $self‐>{maker} = “mazda”; # inherited $self‐>{mpg} = 25; # own attribute return $$;self; }

6.17 Class::Struct module

ƒ Standard module to declare a record‐like class ƒ ‘stttruct’ fftiunction provides for constttructor and accessor metho ds on the fly ƒ Constructor named ‘new’ ƒ Accessor method for each member specified by the hash reference

package Car; use Car; use Class::Struct; struct Car => { $kia = Car ‐> new(); name => ‘$’, # SSlcalar variiblable $kia ‐> name(“CX5”); size => ‘@’, # array variable $aref = $kia‐>size; specs => ‘%’, # hash variable $kia ‐> size(0,100); type => ‘Truck’, # Truck object $href = $kia‐>spp;ecs; } $kia ‐> specs(‘color’, ‘white’); 1;

6.18 Pod

ƒ Plain Old Documentation: simple text markup format ƒ Simple to use, not too expressive ƒ Embed documentation in Perl modules and scripts ƒ Translators: convert Pod to various formats • pod2text, pod2html, pod2latex ƒ CttContent div ide d iitnto paragraphs by empty lines: • verbatim: begins with tabs/spaces (left unformatted) • command: begins with equal sign (format according to directive) • ordinary: begins with something else (minimal formatting) ƒ Perl engine throws out all Pod markup

6.19 Pod (example)

=head1 Boring Module Synopsis

Some I text about the module followed by even more B code

use Boring ; my $object = Boring‐>new();

=cut sub some_fun { print “Documentation ”; print “is for old people!\n”; }

=pod

6.20 Pod (example ctd)

=head2 List of methods

=over 4

=item 1.

First method enforces mild boredom

=item 2.

Second method puts you to sleep

=back

6.21 Exercise (In Class)

ƒ Remove specific field from a list ƒ Suppose you have a row of data stored in a string. The fields of your row may be separated with any delimiter(s). For example: “Name Height Weight 2”. Write a subroutine that deletes the Nth field (N is an argument), and returns the shortened string.

6.22 Common Remarks

ƒ Filehandles: open($fh, “>filename”); print $fh “ABC”, “\t”, “DEF”; # works fine

print $fh, “ABC”, “\t”, “DEF” ; # WRONG: prints to STDOUT ƒ Context: ($x) = (aa,bb,cc); # $x gets value “aa” $x = (aa,bb,cc); # $x gets value “cc” @arr = (aa,bb,cc); $x = @arr; # $x = 3

6.23 Common Remarks

ƒ Efficiency: hashes instead of linear searches # Search $word in @keywords # Method 1: foreach (@keywords) { print “”“yes” if ($wor d eq $)$_); }

# Method 2 (potentiall y more efficient): %h; for (@keywords) { $h{$_}++; } print “yes” if ($h{$word} > 0);

6.24 Common Remarks

ƒ Efficiency: print with comma not “.” print “Mr. ”, $name, “ is next”; # faster print “Mr. ” . “$name” . “ is next”; ƒ DbDebugg ing is problema tic: ‘use warni’ings’ ƒ Planning to share code: ‘use strict’

6.25 Error Handling

ƒ Relevant functions: • Build in: warn, die • Carp module: carp, cluck, croak, confess ƒ Choosing the proper function: • Raise a warning and then continue or terminate execution? • What should the error message report? filename & line number / caller’s info

open($fh, “fname”) or warn “Warning Message”; open($fh, “fname”) or die “Warning Message”;

# warn: just a warning, message printed to STDERR # die: similar to warn, but also calls exit (terminates execution)

6.26 Error Handling (in modules)

ƒ Carp module: ‘use Carp’ • Debugging a module: report module’ s name & line number (warn, die) • Debugging the script: report caller’s info (carp / cluck, croak / confess)

package Job; use Job; use Carp; JbJob::some_fun();

sub some_fun { # Prints the following: warn “Error ”; # warn: “Error at Job.pm line 5.” # carp “Error ”; # warn: “Error at test.pl line 3.” # croak “Error ”; # die: “Error at test.pl line 3.” # cluck “Error ”; # warn: “Error at Job.pm line 5. # Job::some_fun () called at test.pl line 3.” # confess “Error ”; # die: “Error at Job.pm line 5. } # Job::some_fun() called at test.pl line 3.” 1;

6.27