Perl References, Objects and Modules
Document Sample


Perl References, Objects and Modules
Dave Cross
Magnum Solutions Ltd
What We Will Cover
q References
q Modules
q Objects
References
References
q What is a reference?
q Creating references
q Using references
q Why use references?
What is a Reference
q A reference is a bit like a pointer in languages like C and
Pascal (but better)
q A reference is a unique way to refer to a variable
q A reference can always fit into a scalar variable
q A reference looks like SCALAR(0x20026730)
Creating References
q Put \ in front of a variable name
$scalar_ref = \$scalar;
$array_ref = \@array;
$hash_ref = \%hash;
q Can now treat it just like any other scalar
$var = $scalar_ref;
$refs[0] = $array_ref;
$another_ref = $refs[0];
Creating References (cont)
q It's also possible to create references to anonymous variables
(similar to allocating memory using malloc in C)
q Create a reference to an anonymous array using [ ... ]
$arr = [ 'an', 'anon', 'array' ];
q Create a reference to an anonymous hash using { ... }
$hash = { 1 => 'an',
2 => 'anon',
3 => 'hash' };
q Anonymous arrays and hashes have no name. You can only
access them via the reference
Creating References (cont)
q Two ways to create a reference to an array
@arr = (1, 2, 3, 4);
$aref1 = \@arr;
$aref2 = [@arr];
print "$aref1\n$aref2";
q Output:
ARRAY(0x20026800)
ARRAY(0x2002bc00)
q Second method creates a copy of the array
q The same is true of hashes
Using References
q Consider an array variable, @array
q It has two parts, a symbol (@) and a name (array)
q Use {$aref} in place of the name to get back an array that you
have a reference to
@array = @{$aref}; # original array
@rev = reverse @{$aref};
$elem = ${$aref}[0]; # one element
${$aref}[0] = 'foo';
q The same is true of hashes
q Use {$href} in place of the name to get back a hash that you
have a reference to
%hash = %{$href}; # original hash
@keys = keys %{$href};
$elem = ${$href}{key}; # one element
${$href}{key} = 'foo';
Using References (cont)
q Dereferencing syntax can look a bit confusing
print ${$aref}[3];
q Make it easier by using the arrow notation
print $aref->[3];
Using References (cont)
q It is common to store references in arrays or hashes
my %french = (one => 'un',
two => 'deux',
three => 'trois');
my %german = (one => 'ein',
two => 'zwei',
three => 'drei');
my %translate = (french => \%french,
german => \%german);
q Or (using anonymous variables)
my %translate = ( french => { one => 'un',
two => 'deux',
three => 'trois' },
german => { one => 'ein',
two => 'zwei',
three => 'drei' } );
Using References (cont)
q Using references within data structures
my $lang = 'german';
my $num = 'two';
print "The $lang for $num is ";
print ${$translate{$lang}}{$num};
q This is where the arrow notation has a real advantage
print $translate{$lang}->{$num};
Using References (cont)
q You can find out what a reference is referring to using "ref"
$aref = [ 1, 2, 3 ];
print ref $aref; # prints ARRAY
$href = { 1 => 'one', 2 => 'two' };
print ref $href; # prints HASH
q Another example
my @refs = (\$scalar, \@array, \%hash);
foreach (@refs) {
print This is a ', ref $_, "\n";
}
References Exercises
q Create an array and take a reference to it
q Using the reference, print the values in the array
q Now do the same with an anonymous array
q Create hashes to represent at least three people (containing
the keys forename, surname and gender)
q Put references to these hashes in an array called @people
q For each element in @people, print out selected data from the
hash
Exercise Solutions
q Create an array and take a reference to it
my @array = ('some', 'random', 'data');
my $ref = \@array;
q Using the reference, print the values in the array
foreach (@{$ref}) {
print "$_\n";
}
q Now do the same with an anonymous array
my $ref = ['some', 'random', 'data'];
foreach (@{$ref}) {
print "$_\n";
}
Exercise Solutions (cont)
q Create hashes to represent at least three people (containing
the keys forename, surname and gender)
my %buffy = (forename => 'Buffy',
surname => 'Summers',
gender => 'female');
my %willow = (forename => 'Willow',
surname => 'Rosenberg',
gender => 'female');
my %xander = (forename => 'Xander',
surname => 'Harris',
gender => 'male');
q Put references to these hashes in an array called @people
my @people = (\%buffy, \%xander, \%willow);
q For each element in @people, print out selected data from the
hash
foreach (@people) {
print "$_->{forename} $_->{surname} is $_->{gender}\n";
}
Why Use References
q What does this do?
@arr1 = (1, 2, 3);
@arr2 = (4, 5, 6);
check_size(@arr1, @arr2);
sub check_size {
my (@a1, @a2) = @_;
print @a1 == @a2 ? 'Yes' : 'No';
}
q This doesn't work. Why?
q Arrays are combined in @_
q All elements end up in @a1
q How do we fix it?
q Pass references to the arrays
Why Use References (cont)
q Another attempt
@arr1 = (1, 2, 3);
@arr2 = (4, 5, 6);
check_size(\@arr1, \@arr2);
sub check_size {
my ($a1, $a2) = @_;
print @$a1 == @$a2 ? 'Yes' : 'No';
}
q Passing references means there is no list assignment
q All arrays are distributed correctly
q Note: @$a1 is a shortcut for @{$a1}
Why Use References (cont)
q Another use - complex data structures
q Try to create a 2D array in Perl
q First attempt
@arr_2d = ((1, 2, 3),
(4, 5, 6),
(7, 8, 9));
q This doesn't work
q @arr_2d contains (1, 2, 3, 4, 5, 6, 7, 8, 9)
q Any element in an array can only contain a scalar value
q This is known a array flattening
Why Use References (cont)
q 2D Array using references
@arr_2d = ([1, 2, 3],
[4, 5, 6],
[7, 8, 9]);
q But how do you access individual elements?
q $arr_2d[1] is ref to array (4, 5, 6)
q $arr_2d[1]->[1] is element 5
q You can even omit intermediate arrows
$arr_2d[1][1]
Why Use References (cont)
q Another version (using anonymous arrays)
$arr_2d = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]];
q $arr_2d->[1] is ref to array (4, 5, 6)
q $arr_2d->[1]->[1] is element 5
q Simplify to $arr_2d->[1][1]
q First arrow cannot be omitted
q $arr_2d[1] is different to $arr_2d->[1]
Why Use References (cont)
q More complex data structures
q Suppose you have this data file
Summers,Buffy,Slayer
Giles,Rupert,Watcher
Rosenburg,Willow,Witch
Summers,Dawn,Key
q What's a good data structure?
q Hash for each record
q Hashes ordered in an array
q Array of hash references
Why Use References (cont)
q Building an array of hash references
my @peoples;
my @cols = qw(s_name f_name job);
while (<FILE>) {
chomp;
my %rec;
@rec{@cols} = split /,/;
push @records, \%rec;
}
q That @rec{@cols} is known as a hash slice and it is very
useful
q Using an array of hash references
foreach (@records) {
print "$_->{f_name} $_->{s_name} ";
print "is a $_->{job}\n";
}
Why Use References (cont)
q Many more possibilities
x Hash of hash references
x Hash of array references
x Multiple levels (array of hash of hash of array...)
x Many examples in "perldoc perldsc" (the data structures cookbook)
q More information
x perldoc perlreftut
x perldoc perlref
x perldoc perllol
x perldoc perldsc
Finding, Installing and Using Modules
Finding, Installing and Using Modules
q Finding modules
q Installing modules (hard way and easy way)
q Using modules
x Functional modules vs Object Modules
q Object example (DBI)
q Useful modules
Finding Modules
q Perl comes with over 100 modules (see perldoc perlmodlib
for current list)
q Perl has a repository of freely-available modules - the
Comprehensive Perl Archive Network (CPAN)
x http://www.cpan.org/
x http://search.cpan.org/
q Search by module name, distribution name or author name
q Note: CPAN also contains newer versions of standard
modules
Installing Modules (the hard way)
q Download distribution file
MyModule-X.XX.tar.gz
q Unzip file
gunzip MyModule-X.XX.tar.gz
q Untar file
tar xvf MyModule-X.XX.tar
q Change directory
cd MyModule-X.XX
q Create Makefile
perl Makefile.PL
q Build Module
make
q Test Build
make test
q Install Module
make install
Installing Modules (the hard way) (cont)
q Note: May need root permissions for make install
q You can have your own personal module library
perl Makefile.PL PREFIX=~/perl
q Need to adjust @INC
x use lib '/home/dave/perl/lib';
x export PERL5LIB=/home/dave/perl/lib
Installing Modules (the easy way)
q Note: May not work (or may need some configuration)
through a firewall
q CPAN.pm is included with newer Perls
q Automatically carries out installation process
q Can also handle required modules
q Still need to be root
q Using CPAN.pm
perl -MCPAN -eshell
CPAN> install My::Module
q Or
perl -MCPAN -e"install 'My::Module'"
q See also CPANPLUS.pm (on CPAN)
Installing Modules (the easy way, for Windows)
q ActivePerl comes with the Perl Package Manager (PPM)
q This makes it easy to install modules
C:\> ppm
PPM interactive shell (2.0) - type 'help' for available commands
PPM> install XML-Parser
q Type "help" for list of commands
q ActiveState is working on making all of CPAN available
Using Modules
q Having installed a module the documentation is available
using the standard "perldoc" command
perldoc CGI
q Two basic types of module
q Function vs Object
q Functional modules export new subroutines and variables
into your program
q Object modules usually don't
q Difference not clear cut (e.g. CGI.pm)
Using Functional Modules
q Import defaults
use My::Module;
q Import optional components
use My::Module qw(my_sub @my_arr);
q Import defined sets of components
use My:Module qw(:advanced);
q Use imported components
$data = my_sub(@my_arr);
q Exports are defined by module author and should be
documented in module documentation
Using Functional Modules (example)
use POSIX 'strftime';
use CGI ':standard';
my $title = 'The Time';
print header,
start_html(-title=>$title),
h1($title),
p('The time is ', strftime('%H:%M on %A %d %B, %Y',
localtime));
end_html;
q "strftime" is imported from POSIX.pm
q "header", "start_html", "h1", "p", "end_html" (and many more)
are imported from CGI.pm
Using Object Modules
q Use the module
use My::Object;
q Create an object
$obj = My::Object->new;
q Note: "new" is just a convention
q Interact using object's methods
$obj->set_name($name);
q Interface is defined by module author and should be
documented in module documentation
Using Object Modules (example)
use IO::File;
my $in = IO::File->new('in.dat', 'r')
or die $!;
my $out = IO::File->new('out.dat', 'w')
or die $!;
while ($_ = $in->getline) {
$out->print($_) if /some pattern/;
}
q $in and $out are both objects of class IO::File
q Interact with objects thru object methods like "getline" and
"print"
Extended Object Example (DBI)
q Devised by Tim Bunce (author of oraperl)
q Standardised access to any database system
x a bit like ODBC
q Two modules involved
x DataBase Interface (DBI) provides uniform set of database access
functions to programmer
x DataBase Driver (DBD) translates DBI calls into the vendors API
calls
Connecting to a Database
q Connection creates a database handle
x all other communication is through this handle
my $dbh =
DBI->connect("dbi:Oracle:$server",
$user, $pass)
|| die "Can't connect: $DBI::errstr";
q Connection string can vary for different DBD modules
q Database handle is an object
Selecting Data
q Prepare SQL statement
my $sth1 =
$dbh->prepare('select col1
from table1');
my $sth2 =
$dbh->prepare("select col1
from table1
where id_col = $id");
q Check return value (syntax errors)
q $sth1 and $sth2 are also objects (from a different class)
q Execute prepared statement
$sth->execute;
q Still need to check for errors
Selecting Data (cont)
q Fetch data
while (my @row = $sth->fetchrow_array){
print "@row\n";
}
q Fields are returned in the same order as they are defined in
the query
q Other fetch methods are available:
x fetchrow_arrayref
x fetchrow_hashref (keys are column names)
x fetchall_arrayref
x fetch (alias for fetchrow_arrayref)
Inserting, Updating and Deleting
q Statements that don't return data can be executed using the
same method
my $sql = "update table1 set col1 = '$val'
where id_col = $id";
my $sth = $dbh->prepare($sql);
$sth->execute;
q But there's a shortcut
$rows = $dbh->do($sql);
Useful Standard Modules
q constant - Creates constant values
q File::Copy - Copy files
q Time::Local - Convert times to epoch
q POSIX - Interface to POSIX
q Text::Parsewords - Parse words from text
q CGI - CGI applications
q Getopt::Std - Process command line options
q Carp - Better warn and die
q Cwd - Current working directory
q Benchmark - Timing code
q File::Basename - Break up filenames
q Data::Dumper - Dump data to text
Useful CPAN Modules
q Template - Insert data in boilerplate text
q DBI - Database access
q libnet - Various network protocols (e.g. Net::FTP)
q DateTime - Date/Time manipulation
q libwww - HTTP client library
q Number::Format - Formatting numbers
q HTML::Parser - Parsing HTML
q XML::Parser - Parsing XML
q Text::CSV - Parse CSV data
q Regexp::Common - Common regular expressions
q MIME::Lite - Creating and sending MIME emails
q Memoize - Cache function return values
More Information on Modules
q perldoc perlmodlib
q perldoc perlmodinstall
q perldoc CPAN
q perldoc module
Get documents about "