SlideShare a Scribd company logo
Introducing Modern Perl Dave Cross Magnum Solutions Ltd [email_address]
Modern Perl Perl has been around for a long time
Achieved great popularity in the 1990s
“The duct tape of the internet”
Perl has moved on a lot since then
Many people's perceptions of Perl haven't
Modern Perl Keeping up to date with Perl
Surveying modern modules and techniques
A lot to cover
Only an overview
Plenty of pointers to more information
What We Will Cover Template Toolkit
DateTime
DBIx::Class
TryCatch
What We Will Cover Moose
autodie
Catalyst
PSGI/Plack
Schedule 09:00 – Begin
11:00 – Coffee break
13:00 – Lunch
14:00 – Begin
16:00 – Coffee break
17:00 – End
Resources Slides available on-line http://mag-sol.com/train/yapc/2010 Also see Slideshare http://www.slideshare.net/davorg/slideshows Get Satisfaction http://getsatisfaction.com/magnum
Template Toolkit
Templates Many people use templates to produce web pages
Advantages are well known
Standard look and feel (static/dynamic)
Reusable components
Separation of code logic from display logic
Different skill-sets (HTML vs Perl)
DIY Templating Must be easy - so many people do it
See perlfaq4
“How can I expand variables in text strings?”
DIY Templating $text = 'this has a $foo in it and a $bar'; %user_defs = (   foo  => 23,   bar  => 19, ); $text =~ s/(+)/$user_defs{$1}/g;
Don't do that
Templating Options Dozens of template modules on CPAN
Text::Template, HTML::Template, Mason, Template Toolkit
Many, many more
Questions to consider HTML only?
Template language
Template Toolkit http://tt2.org/
Very powerful
Both web and non-web
Simple template language
Plugins give access to much of CPAN
Can use Perl code if you want But don't do that
Good Book Too!
The Template Equation Data + Template = Output
Data + Alternative Template = Alternative Output
Different views of the same data
Only the template changes
Simple TT Example use Template; use My::Object; my ($id, $format) = @ARGV; $format ||= 'html'; my $obj = My::Object->new($id)   or die; my $tt  = Template->new; $tt->process("$format.tt",   { obj => $obj },   "$id.$format")   or die $tt->error;
html.tt <html>   <head>   <title>[% obj.name %]</title>   </head>   <body>   <h1>[% obj.name %]<h1>   <p><img src=“[% obj.img %]” /><br />   [% obj.desc %]</p>   <ul>   [% FOREACH child IN obj.children -%]   <li>[% child.name %]</li>   [% END %]   </body> </html>
text.tt [% obj.name | upper %] Image: [% obj.img %] [% obj.desc %] [% FOREACH child IN obj.children -%]   * [% child.name %] [% END %]
Adding New Formats No new code required
Just add new output template
Perl programmer need not be involved
Equation Revisited Data + Template = Output Template Toolkit Template + Output = Data Template::Extract Data + Output = Template Template::Generate
DateTime
Dates & Times Perl has built-in functions to handle dates and times
time  – seconds since 1st Jan 1970
localtime  – convert to human-readable
timelocal  (in Time::Local) – inverse of localtime
strftime  (in POSIX) – formatting dates and times
Dates & Times on CPAN Look to CPAN for a better answer
Dozens of date/time modules on CPAN
Date::Manip is almost never what you want
Date::Calc, Date::Parse, Class::Date, Date::Simple, etc
Which one do you choose?
Perl DateTime Project http://datetime.perl.org/
&quot;The DateTime family of modules present a unified way to handle dates and times in Perl&quot;
&quot;unified&quot; is good
Dozens of modules that work together in a consistent fashion
Using DateTime use DateTime; my $dt = DateTime->now; say $dt; # 2010-08-02T10:06:07 say $dt->dmy; # 2010-08-02 say $dt->hms; # 10:06:07
Using DateTime use DateTime; my $dt = DateTime->new(year  => 2010,   month => 8,   day  => 2); say $dt->ymd('/');  # 2010/08/02 say $dt->month;  # 8 say $dt->month_name; # August
Arithmetic A DateTime object is a point in time
For date arithmetic you need a duration
Number of years, weeks, days, etc
Arithmetic use DateTime; my $dt = DateTime->new(year => 2010,   month => 8,   day => 2); my $two_weeks = DateTime::Duration->new(weeks => 2); $dt += $two_weeks; say $dt; # 2010-08-16T00:00:00
Formatting Output use DateTime; my $dt = DateTime->new(year => 2010,   month => 4,   day => 14); say $dt->strftime('%A, %d %B %Y'); # Wednesday, 14 April 2010
strftime uses UNIX standards
Control input format with DateTime::Format::Strptime
Parsing & Formatting Ready made parsers and formatters for popular date and time formats
DateTime::Format::HTTP
DateTime::Format::MySQL
DateTime::Format::Excel
DateTime::Format::Baby the big hand is on...
Alternative Calendars Handling non-standard calendars
DateTime::Calendar::Julian
DateTime::Calendar::Hebrew
DateTime::Calendar::Mayan
DateTime::Fiction::JRRTolkien::Shire
Calendar Examples use DateTime::Calendar::Mayan; my $dt = DateTime::Calendar::Mayan->now; say $dt->date; # 12.19.17.9.13
use DateTime::Fiction::JRRTolkien::Shire; my $dt =    DateTime::Fiction::JRRTolkien::Shire->now; say $dt->on_date; # Trewsday 14 Afterlithe 7474
DBIx::Class
Object Relational Mapping Mapping database relations into objects
Tables (relations) map onto classes
Rows (tuples) map onto objects
Columns (attributes) map onto attributes
Don't write SQL
SQL Is Tedious Select the id and name from this table
Select all the details of this row
Select something about related tables
Update this row with these values
Insert a new record with these values
Delete this record
Replacing SQL Instead of
SELECT * FROM  my_table WHERE  my_id = 10
and then dealing with the prepare/execute/fetch code
Replacing SQL We can write
use My::Object; # warning! not a real orm my $obj = My::Object->retrieve(10)
Or something similar
Writing An ORM Layer Not actually that hard to do yourself
Each class needs an associated table
Each class needs a list of columns
Create simple SQL for basic CRUD operations
Don't do that
Perl ORM Options Plenty of choices on CPAN
Class::DBI
Rose::DB::Object
ORLite
DBIx::Class The current favourite Fey::ORM
DBIx::Class Standing on the shoulders of giants
Learning from problems in Class::DBI
More flexible
More powerful
DBIx::Class Example Modeling a CD collection
Three tables
artist (artistid, name)
cd (cdid, artist, title)
track (trackid, cd, title)
Main Schema Define main schema class
Music/DB.pm package Music::DB; use base qw/DBIx::Class::Schema/; __PACKAGE__->load_classes(); 1;
Object Classes - Artist Music/DB/Artist.pm package Music::DB::Artist; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/Core/); __PACKAGE__->table('artist'); __PACKAGE__->add_columns(qw/ artistid   name /); __PACKAGE__->set_primary_key('artistid'); __PACKAGE__->has_many(cds =>   'Music::DB::Cd'); 1;
Object Classes- CD Music/DB/CD.pm package Music::DB::CD; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/Core/); __PACKAGE__->table('cd'); __PACKAGE__->add_columns(qw/ cdid artist   title year /); __PACKAGE__->set_primary_key('cdid'); __PACKAGE__->belongs_to(   artist => 'Music::DB:Artist'); 1;
Inserting Artists my $schema =   Music::DB->connect($dbi_str); my @artists = ('Florence + The Machine',   'Belle and Sebastian'); my $art_rs = $schema->resultset('Artist'); foreach (@artists) {   $art_rs->create({ name => $_ }); }
Inserting CDs Hash of Artists and CDs my %cds = (   'Lungs' =>   'Florence + The Machine',   'The Boy With The Arab Strap'  =>   'Belle and Sebastian',   'Dear Catastrophe Waitress' =>   'Belle and Sebastian', );
Inserting CDs Find each artist and insert CD foreach (keys $cds) {   my ($artist) = $art_rs->search(   { name => $cds{$_} }   );   $artist->add_to_cds({   title => $_,   }); }
Retrieving Data Get CDs by artist my $name = 'Belle and Sebastian'; my ($artist) = $art_rs->search({   name => $name,   }); foreach ($artist->cds) {   say $_->title; }
Searching for Data Search conditions can be more complex
Alternatives $rs->search({year => 2006},   {year => 2007}); Like $rs->search({name =>   { 'like', 'Dav%' }});
Searching for Data Combinations $rs->search({forename =>   { 'like', 'Dav%' },   surname => 'Cross' });
Don't Repeat Yourself There's a problem with this approach
Information is repeated
Columns and relationships defined in the database schema
Columns and relationships defined in class definitions
Repeated Information CREATE TABLE artist (   artistid INTEGER PRIMARY KEY,   name  TEXT NOT NULL  );
Repeated Information package Music::DB::Artist; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/Core/); __PACKAGE__->table('artist'); __PACKAGE__->add_columns(qw/ artistid   name /); __PACKAGE__->set_primary_key('artistid'); __PACKAGE__->has_many(cds =>   'Music::DB::Cd'); 1;
Database Metadata Some people don't put enough metadata in their databases
Just tables and columns
No relationships. No constraints
You may as well make each column VARCHAR(255)
Database Metadata Describe your data in your database
It's what your database is for
It's what your database does best
No Metadata (Excuse 1) &quot;This is the only application that will ever access this database&quot;
Nonsense
All data will be shared eventually

More Related Content

Introducing Modern Perl