![](/static/present/Thoroughly_Modern_Perl.png)
An overview of:
A bit of Perl history
Perl 5 −vs− 6
Perlbrew: Running modern and bleeding-edge programs on the same
system as legacy
Unicode and UTF-8 in the Web world, and how to sort and capitalize
names that are more than just English.
Perl 5's heritage Object system −vs− the "new" Moose
Databases: Old-school SQL with injection vulnerabilities,
SQL::Abstract, and DBIx
Tying it all together: Mojolicious
Download/view:
The [Graph](https://metacpan.org/pod/Graph)
module on CPAN is
mostly well documented. One place it falls short is explaining that not
only can you create weighted edges, you can also use various edge
attributes to calculate different minimum spanning trees (via Dijkstra's
algorithm) based
on any given attribute.
Here we create a small network of railway lines between cities, from
the example on page 9 in John Armstrong's "Track Planning for Realistic
Operation" (Kalmbach Books, 1986):
* There are two routes from A to D: A-B-D, and A-C-D.
* Here we assume that the route via B is longer but faster, and via
C shorter but slower.
* The line continues from D through E and G to H.
* There is a branch line from E to F.
We calculate the shortest route by distance, and then by time.
Note the undocumented attribute parameter to SPT_Dijkstra().
#!/usr/bin/env perl
use strict;
use warnings;
use Graph::Undirected;
my $station_graph = Graph::Undirected->new();
# Add a few cities
$station_graph->add_path(qw(A B D E G H)); # first route via B
$station_graph->add_path(qw(A C D)); # second via C
$station_graph->add_path(qw(E F)); # branch route
# Define characteristics of the alternate routes
# Longer but faster
$station_graph->set_edge_attribute(qw(A B distance), 150);
$station_graph->set_edge_attribute(qw(A B time), 3.1);
# Shorter yet slower
$station_graph->set_edge_attribute(qw(A C distance), 120);
$station_graph->set_edge_attribute(qw(A C time), 3.3);
# Find spanning tree in distance
my $sptg1 = $station_graph->SPT_Dijkstra(attribute => 'distance');
print "Shortest Distance: ". join('|',$sptg1->SP_Dijkstra('A','H'));
print "\n";
# Clear cache (required for recalculation)
$station_graph->SPT_Dijkstra_clear_cache();
# Find spanning tree in time
my $sptg2 = $station_graph->SPT_Dijkstra(attribute => 'time');
print "Shortest Time: ". join('|',$sptg2->SP_Dijkstra('A','H'));
print "\n";
1;
When run, this shows as follows:
$ perl Graph.pl
Shortest Distance: A|C|D|E|G|H
Shortest Time: A|B|D|E|G|H
If you want to use a directed graph, create the graph by replacing that
line with:
my $station_graph = Graph::Directed->new();
and be sure to specify the starting node for the spanning trees:
my $sptg1 = $station_graph->SPT_Dijkstra(attribute => 'distance', first_root => 'A');
…
my $sptg2 = $station_graph->SPT_Dijkstra(attribute => 'time', first_root => 'A');
Why? There's still nothing like printed documentation when you're
learning a new subject. Or perhaps you'd like a PDF document to view on
your tablet.
Here's the quickest way to create a PDF from any Perl documentation on
your system. For example, let's do the CPAN module SQL::Abstract:
pod2pdf --pagesize=letter `perldoc -l SQL::Abstract` > /tmp/SQL_Abstract.pdf`
Now you can view or print that. I find print 2-up pages, double-sided
(4 total pages per sheet) is a handy and space-saving yet still
readable. You might find it useful to reduce the PDF margins and let
evince
or okular
manage the actual 2-up physical margins later:
pod2pdf --margins 18 --pagesize=letter `perldoc -l SQL::Abstract` > /tmp/SQL_Abstract.pdf
The margins parameter is in printer's points (1/72 inch) and 18pt =
¼inch (0.635cm). You can also specify --left-margin
as well as right,
top, and bottom margins individually.
When printing several PDFs together, you may want to suppress blank
pages. This is important when using double-sided or 2-up printing. To
join several PDFs together for printing, you can use:
pdfunite a-in.pdf b-in.pdf output.pdf
If you are having difficulty printing documentation that contains
Unicode,
cpanm App::pod2pdf Paper::Specs
Modern Perl (see also the Modern Perl book)
is based on, among other things, Moose
as an object system, built on Perl 5's innate but spare O-O abilities.
This introduction
[houseabsolute.com] explains not only Moose itself but quickly, and
fairly painlessly, brings you into modern object orientation.
Also, Moose Is Perl − A Guide to the New Revolution
[oreilly.com] − an over 400-page guide from the introductory to the
detailed.
What modules are installed on my system?
# <span style="text-decoration: underline;">cpan -l</span>
From the cpan prompt, how can I tell whether a module is already
installed, and what version?
cpan> <span style="text-decoration: underline;">i <em>module_name</em></span>
And how can I tell which modules are out-of-date or have updated
versions?
cpan> <span style="text-decoration: underline;">r</span>
…which gives a result like:
Package namespace installed latest in CPAN file
Archive::Extract 0.70 0.72 BINGOS/Archive-…0.72.tar.gz
Attribute::Handlers 0.94 0.96 SMUELLER/Attribute…0.96.tar.gz
AutoLoader 5.73 5.74 SMUELLER/AutoLoader-5.74.tar.gz
B::Debug 1.18 1.19 RURBAN/B-Debug-1.19.tar.gz
Carp 1.29 1.3301 ZEFRAM/Carp-1.3301.tar.gz
Clone 0.36 0.37 GARU/Clone-0.37.tar.gz
Compress::Bzip2 2.16 2.17 RURBAN/Compress-….tar.gz
DB_File 1.827 1.831 PMQS/DB_File-1.831.tar.gz
Data::Dumper 2.145 2.151 SMUELLER/Data…151.tar.gz
…