Introduction to Modern Perl

  • 18,012 views
Uploaded on

Version of my "Introduction to Modern Perl" training course that I gave at YAPC::Europe 2011 in Riga.

Version of my "Introduction to Modern Perl" training course that I gave at YAPC::Europe 2011 in Riga.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
18,012
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
110
Comments
0
Likes
4

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Introducing Modern Perl Dave Cross Magnum Solutions Ltd [email_address]
  • 2. Modern Perl
    • Perl has been around for a long time
    • 3. Achieved great popularity in the 1990s
    • 4. “The duct tape of the internet”
    • 5. Perl has moved on a lot since then
    • 6. Many people's perceptions of Perl haven't
  • 7. Modern Perl
    • Keeping up to date with Perl
    • 8. Surveying modern modules and techniques
    • 9. A lot to cover
    • 10. Only an overview
    • 11. Plenty of pointers to more information
  • 12. What We Will Cover
  • 17. What We Will Cover
  • 21. Schedule
    • 10:00 Start
    • 22. 11:30 – 11:45 Coffee
    • 23. 13:00 – 14:00 Lunch
    • 24. 15:30 – 15:40 Coffee
    • 25. 18:00 End
    • 26. 18:00 Pre-Conference Meeting
  • 27. Resources
    • Slides available on-line
      • http://mag-sol.com/train/yapc/2011
    • Also see Slideshare
      • http://www.slideshare.net/davorg/slideshows
    • Get Satisfaction
      • http://getsatisfaction.com/magnum
  • 28. Modern Core Perl
  • 29. Perl Releases
    • Perl 5 has moved to a regular release cycle
    • 30. Major release every year
    • 31. Minor releases when required
  • 32. Release Numbering
    • Even major numbers are production releases
      • 5.10, 5.12, 5.14
    • Odd major numbers are dev releases
      • 5.11, 5.13, 5.15
  • 33. Perl 5.10
    • Released 18 th Dec 2007
      • Perl's 20 th birthday
    • Many new features
    • 34. Well worth upgrading
  • 35. New Features
  • 40. New Features
    • State variables
    • 41. Stacked file tests
    • 42. Regex improvements
    • 43. Many more
  • 44. Defined Or
    • Boolean expressions “short-circuit”
    • 45. $val = $val || $default;
    • 46. $val ||= $default;
    • 47. What if 0 is a valid value?
    • 48. Need to check “definedness”
    • 49. $val = defined $val ? $val : $default;
    • 50. $val = $default unless defined $val;
  • 51. Defined Or
    • The defined or operator makes this easier
    • 52. $val = $val // $default;
    • 53. A different slant on truth
    • 54. Checks definedness
    • 55. Shortcircuit version too
    • 56. $val //= $value;
  • 57. Switch Statement
    • Switch.pm was added with Perl 5.8
    • 58. Source filter
    • 59. Parser limitations
      • Regular expressions
      • 60. eval
    • 5.10 introduces a build-in switch statement
  • 61. Given ... When
    • Switch is spelled “given”
    • 62. Case is spelled “when”
    • 63. Powerful matching syntax
  • 64. Given Example
    • given ($foo) { when (/^abc/) { $abc = 1; } when (/^def/) { $def = 1; } when (/^xyz/) { $xyz = 1; } default { $nothing = 1; } }
  • 65. New Keywords
  • 69. given
    • given(EXPR)
    • 70. Assigns the result of EXPR to $_ within the following block
    • 71. Similar to do { my $_ = EXPR; ... }
  • 72. when
    • when (EXPR)
    • 73. Uses smart matching to compare $_ with EXPR
    • 74. Equivalent to when ($_ ~~ EXPR)
    • 75. ~~ is the new smart match operator
    • 76. Compares two values and “does the right thing”
  • 77. default
    • default defines a block that is executed if no when blocks match
    • 78. default block is optional
  • 79. continue
    • continue keyword falls through to the next when block
    • 80. Normal behaviour is to break out of given block once the first when condition is matched
  • 81. continue
    • given($foo) { when (/x/) { say '$foo contains an x'; continue } when (/y/) { say '$foo contains a y' } default { say '$foo contains no x or y' } }
  • 82. Smart Matching
    • ~~ is the new Smart Match operator
    • 83. Different kinds of matches
    • 84. Dependent on the types of the operands
    • 85. See “perldoc perlsyn” for the full details
    • 86. CAVEAT: Subject to change
  • 87. Smart Match Examples
    • $foo ~~ $bar; # == or cmp
    • 88. @foo ~~ $bar; # array contains value
    • 89. %foo ~~ $bar; # hash key exists
    • 90. $foo ~~ qr{$bar}; # regex match
    • 91. @foo ~~ @bar; # arrays are identical
    • 92. %foo ~~ %bar; # hash keys match
    • 93. Many more alternatives
  • 94. say()
    • say() is a new alternative to print()
    • 95. Adds a new line at the end of each call
    • 96. say($foo); # print $foo, “n”;
    • 97. Two characters shorter than print
    • 98. Less typing
  • 99. Lexical $_
    • $_ is a package variable
    • 100. Always exists in main package
    • 101. Can lead to subtle bugs when not localised correctly
    • 102. Can now use my $_ to create a lexically scoped variable called $_
  • 103. State Variables
    • Lexical variables disappear when their scope is destroyed
    • 104. sub variables { my $x; say ++$x; } variables() for 1 .. 3;
  • 105. State Variables
    • State variables retain their value when their scope is destroyed
    • 106. sub variables { state $x; say ++$x; } variables() for 1 .. 3;
    • 107. Like static variables in C
  • 108. Stacked File Tests
    • People often think you can do this
    • 109. -f -w -x $file
    • 110. Previously you couldn't
    • 111. Now you can
    • 112. Equivalent to
    • 113. -x $file && -w _ && -f _
  • 114. Regex Improvements
    • Plenty of regular expression improvements
    • 115. Named capture buffers
    • 116. Possessive quantifiers
    • 117. Relative backreferences
    • 118. New escape sequences
    • 119. Many more
  • 120. Named Capture Buffers
    • Variables $1, $2, etc change if the regex is altered
    • 121. Named captures retain their names
    • 122. (?<name> ... ) to define
    • 123. Use new %+ hash to access them
  • 124. Named Capture Example
    • while (<DATA>) { if (/(?<header>[ws]+) :s+(?<value>.+)/x) { print &quot;$+{header} -> &quot;; print &quot;$+{value}n&quot;; } }
  • 125. Possessive Quantifiers
  • 131. Relative Backreferences
    • g{N}
    • 132. More powerful version of 1 , 2 , etc
    • 133. g{1} is the same as 1
    • 134. g{-1} is the last capture buffer
    • 135. g{-2} is the one before that
  • 136. New Escape Sequences
    • h – Horizontal white space
    • 137. v – Vertical white space
    • 138. Also H and V
  • 139. Accessing New Features
    • Some new features would break backwards compatibility
    • 140. They are therefore turned off by default
    • 141. Turn them on with the feature pragma
    • 142. use feature 'say';
    • 143. use feature 'switch';
    • 144. use feature 'state';
    • 145. use feature ':5.10';
  • 146. Implicit Loading
    • Two ways to automatically turn on 5.10 features
    • 147. Require a high enough version of Perl
    • 148. use 5.10.0; # Or higher
    • 149. -E command line option
    • 150. perl -e 'say “hello”'
    • 151. perl -E 'say “hello”'
  • 152. Perl 5.12
    • Released 12 April 2010
      • 5.12.4 20 June 2011
    • Many new enhancements
  • 153. 5.12 Enhancements
  • 156. 5.12 Enhancements
    • package NAME VERSION syntax
    • 157. ... operator
    • 158. Implicit strictures
    • 159. Y2038 compliance
  • 160. ... Operator
    • Called the “yada-yada” operator
    • 161. Used to stand in for unwritten code
    • 162. sub unimplemented { ... }
    • 163. Code compiles
    • 164. Throws an “unimplemented” exception when run
  • 165. package NAME VER
    • Declare the version of a package in the package declaration
    • 166. package My::Package 1.23;
    • 167. Equivalent to
    • 168. package My::Package; our $VERSION = 1.23;
  • 169. Implicit Strictures
    • Requiring a version of Perl greater than 5.11 implicitly turns on use strict
    • 170. use 5.12.0;
    • 171. Is equivalent to
    • 172. use strict; use feature ':5.12';
  • 173. Y2038 Compliance
    • Core time functions are now Y2038 compliant
  • 174. Smart Match Changes
    • Some changes to Smart Match operator
    • 175. No longer commutative
    • 176. See new table in perlsyn
    • 177. CAVEAT: More changes coming
  • 178. New Modules
    • Some new modules in the standard distribution
    • 179. autodie
    • 180. parent
      • Better version of base.
  • 181. Perl 5.14
    • Released 14 May 2011
      • 5.14.1 16 June 2011
    • Many new enhancements
    • 182. 5.16 due spring 2012
  • 183. 5.14 Enhancements
    • Non-destructive substitution
    • 184. Container functions accept references
    • 185. Package block
    • 186. New modules
  • 187. Non-destructive substitution
    • New /r option on s/// and tr///
    • 188. Copies input
    • 189. Acts on copy
    • 190. Original unmodifed
    • 191. $_ = 'cat'; $new = s/cat/dog/r'; # $_ remains 'cat'
  • 192. Container functions accept references
    • Array & hash functions used to require arrays or hashes
      • push @array, $value
      • 193. @keys = keys %hash
    • Even if you have a reference
      • push @$arrayref, $value
      • 194. @keys = keys %$hashref
  • 195. Container functions accept references
    • Array & hash functions now accept references
      • push $array_ref, $value
      • 196. @keys = keys $hash_ref
    • Currently experimental
  • 197. Package block
    • Attach a code block to a package declaration
    • 198. package MyPackage { ... }
    • 199. Equivalent to
    • 200. { package MyPackage; ... }
    • 201. Can also declare a version
    • 202. package MyPackage 1.23 { ... }
  • 203. New Modules
    • Many modules for parsing META files
    • 204. CPAN::Meta::YAML & JSON::PP
    • 205. CPAN::Meta
    • 206. CPAN::Meta::Spec & CPAN::Meta::History
    • 207. Module::Metadata
  • 208. New Modules
    • Other new modules
    • 209. CPAN::Meta::YAML & JSON::PP
    • 210. CPAN::Meta
    • 211. CPAN::Meta::Spec & CPAN::Meta::History
    • 212. Module::Metadata
  • 213. More Information
    • perldoc perl5100delta
    • 214. perldoc perl5120delta
    • 215. Perldoc perl5140delta
  • 216. Template Toolkit
  • 217. Templates
    • Many people use templates to produce web pages
    • 218. Advantages are well known
    • 219. Standard look and feel (static/dynamic)
    • 220. Reusable components
    • 221. Separation of code logic from display logic
    • 222. Different skill-sets (HTML vs Perl)
  • 223. DIY Templating
    • Must be easy - so many people do it
    • 224. See perlfaq4
    • 225. “How can I expand variables in text strings?”
  • 226. DIY Templating
    • $text = 'this has a $foo in it and a $bar'; %user_defs = ( foo => 23, bar => 19, ); $text =~ s/$(w+)/$user_defs{$1}/g;
    • 227. Don't do that
  • 228. Templating Options
    • Dozens of template modules on CPAN
    • 229. Text::Template, HTML::Template, Mason, Template Toolkit
    • 230. Many, many more
    • 231. Questions to consider
      • HTML only?
      • 232. Template language
  • 233. Template Toolkit
    • http://tt2.org/
    • 234. Very powerful
    • 235. Both web and non-web
    • 236. Simple template language
    • 237. Plugins give access to much of CPAN
    • 238. Can use Perl code if you want
      • But don't do that
  • 239. Good Book Too!
  • 240. The Template Equation
    • Data + Template = Output
    • 241. Data + Alternative Template = Alternative Output
    • 242. Different views of the same data
    • 243. Only the template changes
  • 244. 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(&quot;$format.tt&quot;, { obj => $obj }, &quot;$id.$format&quot;) or die $tt->error;
  • 245. 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>
  • 246. text.tt
    • [% obj.name | upper %] Image: [% obj.img %] [% obj.desc %] [% FOREACH child IN obj.children -%] * [% child.name %] [% END %]
  • 247. Adding New Formats
    • No new code required
    • 248. Just add new output template
    • 249. Perl programmer need not be involved
  • 250. Equation Revisited
    • Data + Template = Output
      • Template Toolkit
    • Template + Output = Data
      • Template::Extract
    • Data + Output = Template
      • Template::Generate
  • 251. DateTime
  • 252. Dates & Times
    • Perl has built-in functions to handle dates and times
    • 253. time – seconds since 1st Jan 1970
    • 254. localtime – convert to human-readable
    • 255. timelocal (in Time::Local) – inverse of localtime
    • 256. strftime (in POSIX) – formatting dates and times
  • 257. Dates & Times on CPAN
    • Look to CPAN for a better answer
    • 258. Dozens of date/time modules on CPAN
    • 259. Date::Manip is almost never what you want
    • 260. Date::Calc, Date::Parse, Class::Date, Date::Simple, etc
    • 261. Which one do you choose?
  • 262. Perl DateTime Project
    • http://datetime.perl.org/
    • 263. &quot;The DateTime family of modules present a unified way to handle dates and times in Perl&quot;
    • 264. &quot;unified&quot; is good
    • 265. Dozens of modules that work together in a consistent fashion
  • 266. 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
  • 267. 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
  • 268. Arithmetic
    • A DateTime object is a point in time
    • 269. For date arithmetic you need a duration
    • 270. Number of years, weeks, days, etc
  • 271. 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
  • 272. 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
    • 273. strftime uses UNIX standards
    • 274. Control input format with DateTime::Format::Strptime
  • 275. Parsing & Formatting
    • Ready made parsers and formatters for popular date and time formats
    • 276. DateTime::Format::HTTP
    • 277. DateTime::Format::MySQL
    • 278. DateTime::Format::Excel
    • 279. DateTime::Format::Baby
      • the big hand is on...
  • 280. Alternative Calendars
    • Handling non-standard calendars
    • 281. DateTime::Calendar::Julian
    • 282. DateTime::Calendar::Hebrew
    • 283. DateTime::Calendar::Mayan
    • 284. DateTime::Fiction::JRRTolkien::Shire
  • 285. Calendar Examples
    • use DateTime::Calendar::Mayan; my $dt = DateTime::Calendar::Mayan->now; say $dt->date; # 12.19.17.9.13
    • 286. use DateTime::Fiction::JRRTolkien::Shire; my $dt = DateTime::Fiction::JRRTolkien::Shire->now; say $dt->on_date; # Trewsday 14 Afterlithe 7474
  • 287. DBIx::Class
  • 288. Object Relational Mapping
    • Mapping database relations into objects
    • 289. Tables (relations) map onto classes
    • 290. Rows (tuples) map onto objects
    • 291. Columns (attributes) map onto attributes
    • 292. Don't write SQL
  • 293. SQL Is Tedious
    • Select the id and name from this table
    • 294. Select all the details of this row
    • 295. Select something about related tables
    • 296. Update this row with these values
    • 297. Insert a new record with these values
    • 298. Delete this record
  • 299. Replacing SQL
    • Instead of
    • 300. SELECT * FROM my_table WHERE my_id = 10
    • 301. and then dealing with the prepare/execute/fetch code
  • 302. Replacing SQL
    • We can write
    • 303. use My::Object; # warning! not a real orm my $obj = My::Object->retrieve(10)
    • 304. Or something similar
  • 305. Writing An ORM Layer
    • Not actually that hard to do yourself
    • 306. Each class needs an associated table
    • 307. Each class needs a list of columns
    • 308. Create simple SQL for basic CRUD operations
    • 309. Don't do that
  • 310. Perl ORM Options
    • Plenty of choices on CPAN
    • 311. Class::DBI
    • 312. Rose::DB::Object
    • 313. ORLite
    • 314. DBIx::Class
      • The current favourite
    • Fey::ORM
  • 315. DBIx::Class
    • Standing on the shoulders of giants
    • 316. Learning from problems in Class::DBI
    • 317. More flexible
    • 318. More powerful
  • 319. DBIx::Class Example
    • Modeling a CD collection
    • 320. Three tables
    • 321. artist (artistid, name)
    • 322. cd (cdid, artist, title)
    • 323. track (trackid, cd, title)
  • 324. Main Schema
    • Define main schema class
    • 325. Music/DB.pm
    • package Music::DB; use base qw/DBIx::Class::Schema/; __PACKAGE__->load_classes(); 1;
  • 326. 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;
  • 327. 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;
  • 328. 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 => $_ }); }
  • 329. 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', );
  • 330. Inserting CDs
    • Find each artist and insert CD
    • foreach (keys %cds) { my ($artist) = $art_rs->search( { name => $cds{$_} } ); $artist->add_to_cds({ title => $_, }); }
  • 331. Retrieving Data
    • Get CDs by artist
    • my $name = 'Belle and Sebastian'; my ($artist) = $art_rs->search({ name => $name, }); foreach ($artist->cds) { say $_->title; }
  • 332. Searching for Data
    • Search conditions can be more complex
    • 333. Alternatives
      • $rs->search({year => 2006}, {year => 2007});
    • Like
      • $rs->search({name => { 'like', 'Dav%' }});
  • 334. Searching for Data
    • Combinations
      • $rs->search({forename => { 'like', 'Dav%' }, surname => 'Cross' });
  • 335. Don't Repeat Yourself
    • There's a problem with this approach
    • 336. Information is repeated
    • 337. Columns and relationships defined in the database schema
    • 338. Columns and relationships defined in class definitions
  • 339. Repeated Information
    • CREATE TABLE artist ( artistid INTEGER PRIMARY KEY, name TEXT NOT NULL );
  • 340. 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;
  • 341. Database Metadata
    • Some people don't put enough metadata in their databases
    • 342. Just tables and columns
    • 343. No relationships. No constraints
    • 344. You may as well make each column VARCHAR(255)
  • 345. Database Metadata
    • Describe your data in your database
    • 346. It's what your database is for
    • 347. It's what your database does best
  • 348. No Metadata (Excuse 1)
    • &quot;This is the only application that will ever access this database&quot;
    • 349. Nonsense
    • 350. All data will be shared eventually
    • 351. People will update your database using other applications
    • 352. Can you guarantee that someone won't use mysql to update your database?
  • 353. No Metadata (Excuse 2)
    • &quot;Database doesn't support those features&quot;
    • 354. Nonsense
    • 355. MySQL 3.x is not a database
      • It's a set of data files with a vaguely SQL-like query syntax
    • MySQL 4.x is a lot better
    • 356. MySQL 5.x is most of the way there
    • 357. Don't be constrained by using inferior tools
  • 358. DBIC::Schema::Loader
    • Creates classes by querying your database metadata
    • 359. No more repeated data
    • 360. We are now DRY
    • 361. Schema definitions in one place
    • 362. But...
    • 363. Performance problems
  • 364. Performance Problems
    • You don't really want to generate all your class definitions each time your program is run
    • 365. Need to generate the classes in advance
    • 366. dump_to_dir method
    • 367. Regenerate classes each time schema changes
  • 368. Alternative Approach
    • Need one canonical definition of the data tables
    • 369. Doesn't need to be SQL DDL
    • 370. Could be Perl code
    • 371. Generate DDL from DBIx::Class definitions
      • Harder approach
      • 372. Might need to generate ALTER TABLE
  • 373. Conclusions
    • ORM is a bridge between relational objects and program objects
    • 374. Avoid writing SQL in common cases
    • 375. DBIx::Class is the currently fashionable module
    • 376. Caveat: ORM may be overkill for simple programs
  • 377. More Information
    • Manual pages (on CPAN)
    • 378. DBIx::Class
    • 379. DBIx::Class::Manual::*
    • 380. DBIx::Class::Schema::Loader
    • 381. Mailing list (Google for it)
  • 382. TryCatch
  • 383. Error Handling
    • How do you handle errors in your code?
    • 384. Return error values from subroutines
    • 385. sub get_object { my ($class, $id) = @_; if (my $obj = find_obj_in_db($id)) { return $obj; } else { return; } }
  • 386. Problems
    • What if someone doesn't check return code?
    • 387. my $obj = MyClass->get_object(100); print $obj->name; # error
    • 388. Caller assumes that $obj is a valid object
    • 389. Bad things follow
  • 390. Basic Exceptions
    • Throw an exception instead
    • 391. sub get_object { my ($class, $id) = @_; if (my $obj = find_obj_in_db($id)) { return $obj; } else { die “No object found with id: $id”; } }
    • 392. Now caller has to deal with exceptions
  • 393. Dealing with Exceptions
    • Use eval to catch exceptions
    • 394. my $obj = eval { MyClass->get_object(100) }; if ($@) { # handle exception... } else { print $obj->name; # error }
  • 395. Exceptions as Objects
    • $@ can be set to an object
    • 396. sub get_object { my ($class, $id) = @_; if (my $obj = find_obj_in_db($id)) { return $obj; } else { die MyException->new( type => 'obj_not_found', id => $id, ); } }
  • 397. Try Catch
    • TryCatch adds “syntactic sugar”
    • 398. try { ... } catch ($e) { ... }
    • 399. Looks a lot like many other languages
  • 400. TryCatch with Scalar
    • try { some_function_that_might_die(); } catch ($e) { if ($e =~ /some error/) { # handle error } else { die $e; } }
  • 401. TryCatch with Object
    • try { some_function_that_might_die(); } catch ($e) { if ($e->type eq 'file') { # handle error } else { die $e; } }
  • 402. Better Checks
    • try { some_function_that_might_die(); } catch (My::Error $e) { # handle error }
  • 403. Even Better Checks
    • try { some_function_that_might_die(); } catch (HTTP::Error $e where { $e->code == 404 }) { # handle 404 error }
  • 404. Multiple Checks
    • try { some_function_that_might_die(); } catch (HTTP::Error $e where { $e->code == 404 }) { # handle 404 error } catch (HTTP::Error $e where { $e->code == 500 }) { # handle 500 error } catch (HTTP::Error $e) { # handle other HTTP error } catch ($e) { # handle other error }
  • 405. More Information
    • perldoc TryCatch
    • 406. See also Try::Tiny
  • 407. Moose
  • 408. Moose
    • A complete modern object system for Perl 5
    • 409. Based on Perl 6 object model
    • 410. Built on top of Class::MOP
      • MOP - Meta Object Protocol
      • 411. Set of abstractions for components of an object system
      • 412. Classes, Objects, Methods, Attributes
    • An example might help
  • 413. Moose Example
    • package Point; use Moose; has 'x' => (isa => 'Int', is => 'ro'); has 'y' => (isa => 'Int', is => 'rw'); sub clear { my $self = shift; $self->{x} = 0; $self->y(0); }
  • 414. Understanding Moose
    • There's a lot going on here
    • 415. use Moose
      • Loads Moose environment
      • 416. Makes our class a subclass of Moose::Object
      • 417. Turns on strict and warnings
  • 418. Creating Attributes
    • has 'x' => (isa => 'Int', is => 'ro')
      • Creates an attribute called 'x'
      • 419. Constrainted to be an integer
      • 420. Read-only accessor
    • has 'y' => (isa => 'Int', is => 'rw')
  • 421. Defining Methods
    • sub clear { my $self = shift; $self->{x} = 0; $self->y(0); }
    • Standard method syntax
    • 422. Uses generated method to set y
    • 423. Direct hash access for x
  • 424. Subclassing
    • package Point3D; use Moose; extends 'Point'; has 'z' => (isa => 'Int'); after 'clear' => sub { my $self = shift; $self->{z} = 0; };
  • 425. Subclasses
    • extends 'Point'
      • Similar to use base
      • 426. Overwrites @ISA instead of appending
    • has 'z' => (isa = 'Int')
      • Adds new attribute 'z'
      • 427. No accessor function - private attribute
  • 428. Extending Methods
    • after 'clear' => sub { my $self = shift; $self->{z} = 0; };
    • 429. New clear method for subclass
    • 430. Called after method for superclass
    • 431. Cleaner than $self->SUPER::clear()
  • 432. Creating Objects
    • Moose classes are used just like any other Perl class
    • 433. $point = Point->new(x => 1, y => 2);
    • 434. $p3d = Point3D->new(x => 1, y => 2, z => 3);
  • 435. More About Attributes
    • Use the has keyword to define your class's attributes
    • 436. has 'first_name' => ( is => 'rw' );
    • 437. Use is to define rw or ro
    • 438. Omitting is gives an attribute with no accessors
  • 439. Getting & Setting
    • By default each attribute creates a method of the same name.
    • 440. Used for both getting and setting the attribute
    • 441. $dave->first_name('Dave');
    • 442. say $dave->first_name;
  • 443. Change Accessor Name
    • Change accessor names using reader and writer
    • 444. has 'name' => ( is => 'rw', reader => 'get_name', writer => 'set_name', );
    • 445. See also MooseX::FollowPBP
  • 446. Required Attributes
    • Moose class attributes are optional
    • 447. Change this with required
    • 448. has 'name' => ( is => 'ro', required => 1, );
    • 449. Forces constructor to expect a name
    • 450. Although that name could be undef
  • 451. Attribute Defaults
    • Set a default value for an attribute with default
    • 452. has 'size' => ( is => 'rw', default => 'medium', );
    • 453. Can use a subroutine reference
    • 454. has 'size' => ( is => 'rw', default => &rand_size, );
  • 455. Attribute Properties
    • lazy
      • Only populate attribute when queried
    • trigger
      • Subroutine called after the attribute is set
    • isa
      • Set the type of an attribute
    • Many more
  • 456. More Moose
    • Many more options
    • 457. Support for concepts like delegation and roles
    • 458. Powerful plugin support
      • MooseX::*
    • Lots of work going on in this area
  • 459. autodie
  • 460. More on Exceptions
    • Exceptions force callers to deal with error conditions
    • 461. But you have to explicitly code to throw exceptions
    • 462. open my $fh, '<', 'somefile.txt' or die $!;
    • 463. What if you forget to check the return value?
  • 464. Not Checking Errors
    • open my $fh, '<', 'somefile.txt'; while (<$fh>) { # do something useful }
    • 465. If the 'open' fails, you can't read any data
    • 466. You might not even get any warnings
  • 467. Automatic Exceptions
    • use Fatal qw(open);
    • 468. Comes with Perl since 5.003
    • 469. Errors in built-in functions become fatal errors
    • 470. This solves our previous problem
    • 471. open my $fh, '<', 'somefile.txt';
  • 472. However
    • Fatal.pm has its own problems
    • 473. Unintelligent check for success or failure
    • 474. Checks return value for true/false
    • 475. Assumes false is failure
    • 476. Can't be used if function can legitimately return a false value
      • e.g. fork
  • 477. Also
    • Nasty error messages
    • 478. $ perl -MFatal=open -E'open my $fh, &quot;notthere&quot;' Can't open(GLOB(0x86357a4), notthere): No such file or directory at (eval 1) line 4 main::__ANON__('GLOB(0x86357a4)', 'notthere') called at -e line 1
  • 479. Enter autodie
    • autodie is a cleverer Fatal
    • 480. In Perl core since 5.10.1
    • 481. Fatal needed a list of built-ins
    • 482. autodie assumes all built-ins
      • use autodie;
  • 483. Turning autodie on/off
    • Lexically scoped
      • use autodie;
      • 484. no autodie;
    • Turn off for specific built-ins
      • no autodie 'open';
  • 485. Failing Calls
    • autodie has more intelligence about failing calls
    • 486. Not just a boolean check
    • 487. Understands fork, system, etc
  • 488. Errors are Objects
    • Errors thrown by autodie are objects
    • 489. Can be inspected for details of the error
    • 490. try { open my $fh, '<', 'not-there'; } catch ($e) { warn 'Error opening ', $e->args->[-1], &quot;n&quot;; warn 'File: ', $e->file, &quot;n&quot;; warn 'Function: ', $e->function, &quot;n&quot;; warn 'Package: ', $e->package, &quot;n&quot;; warn 'Caller: ', $e->caller, &quot;n&quot;; warn 'Line: ', $e->line, &quot;n&quot;; }
  • 491. Nicer Errors Too
    • $ perl -Mautodie -E'open my $fh, &quot;not-there&quot;' Can't open($fh, 'not-there'): No such file or directory at -e line 1
  • 492. More Information
    • perldoc Fatal
    • 493. perldoc autodie
    • 494. autodie - The art of Klingon Programming
      • http://perltraining.com.au/tips/2008-08-20.html
  • 495. Catalyst
  • 496. MVC Frameworks
    • MVC frameworks are a popular way to write applications
      • Particularly web applications
  • 497. M, V and C
    • Model
      • Data storage & data access
    • View
      • Data presentation layer
    • Controller
      • Business logic to glue it all together
  • 498. MVC Examples
  • 504. MVC in Perl
    • Maypole
      • The original Perl MVC framework
    • CGI::Application
      • Simple MVC for CGI programming
    • Jifty
      • Developed and used by Best Practical
    • Catalyst
      • Currently the popular choice
  • 505. Newer MVC in Perl
  • 508. Catalyst
    • MVC framework in Perl
    • 509. Building on other heavily-used tools
    • 510. Model uses DBIx::Class
    • 511. View uses Template Toolkit
    • 512. These are just defaults
    • 513. Can use anything you want
  • 514. Simple Catalyst App
    • Assume we already have model
      • CD database from DBIx::Class section
    • Use catalyst.pl to create project
    • 515. $ catalyst.pl CD created &quot;CD&quot; created &quot;CD/script&quot; created &quot;CD/lib&quot; created &quot;CD/root&quot; ... many more ...
  • 516. What Just Happened?
    • Catalyst just generated a lot of useful stuff for us
    • 517. Test web servers
      • Standalone and FastCGI
    • Configuration files
    • 518. Test stubs
    • 519. Helpers for creating models, views and controllers
  • 520. A Working Application
    • We already have a working application
    • 521. $ CD/script/cd_server.pl ... lots of output [info] CD powered by Catalyst 5.7015 You can connect to your server at http://localhost:3000
    • 522. Of course, it doesn't do much yet
  • 523. Simple Catalyst App
  • 524. Next Steps
    • Use various helper programs to create models and views for your application
    • 525. Write controller code to tie it all together
    • 526. Many plugins to handle various parts of the process
  • 530. Create a View
    • $ script/cd_create.pl view Default TT exists &quot;/home/dave/training/cdlib/CD/script/../lib/CD/View&quot; exists &quot;/home/dave/training/cdlib/CD/script/../t&quot; created &quot;/home/dave/training/cdlib/CD/script/../lib/CD/View/Default.pm&quot; created &quot;/home/dave/training/cdlib/CD/script/../t/view_Default.t&quot;
  • 531. Remove Default Message
    • In lib/CD/Controller/Root.pm
    • 532. sub index :Path :Args(0) { my ( $self, $c ) = @_; # Hello World $c->response_body($c->welcome_message); }
    • 533. Remove response_body line
    • 534. Default behaviour is to render index.tt
    • 535. Need to create that
  • 536. index.tt
    • root/index.tt
    • <html> <head> <title>CDs</title> </head> <body> <ul> [% FOREACH cd IN [ 1 .. 10 ] %] <li>CD [% cd %]</li> [% END %] </ul> </body> </html>
  • 537. New Front Page
  • 538. Adding Data
    • Of course that's hard-coded data
    • 539. Need to add a model class
    • 540. And then more views
    • 541. And some controllers
    • 542. There's a lot to do
    • 543. I recommend working through a tutorial
  • 544. Easier Catalyst
    • A lot of web applications do similar things
    • 545. Given a database
    • 546. Produce screens to edit the data
    • 547. Surely most of this can be automated
    • 548. It's called Catalyst::Plugin::AutoCRUD
    • 549. (Demo)
  • 550. Cat::Plugin::AutoCRUD
    • Does a lot of work
    • 551. On the fly
    • 552. For every request
    • 553. No security on table updates
    • 554. So it's not right for every project
    • 555. Very impressive though
  • 556. Conclusions
    • There's a lot to bear in mind when writing a web app
    • 557. Using the right framework can help
    • 558. Catalyst is the most popular Perl framework
    • 559. As powerful as any other framework
      • In any language
    • Lots of work still going on
    • 560. Large team, active development
  • 561. Recommended Book
    • The Definitive Guide to Catalyst
      • Kieren Diment
      • 562. Matt S Trout
  • 563. PSGI/Plack
  • 564. PSGI/Plack
    • “ PSGI is an interface between Perl web applications and web servers, and Plack is a Perl module and toolkit that contains PSGI middleware, helpers and adapters to web servers.”
      • http://plackperl.org/
  • 565. PSGI/Plack
    • PSGI is a specification (based on Python's WSGI)
    • 566. Plack is a reference implementation (based on Ruby's Rack)
  • 567. The Problem
    • There are many ways to write web applications
    • 568. There are many ways to write web applications in Perl
    • 569. Each is subtly different
    • 570. Hard to move an application between server architectures
  • 571. Server Architectures
  • 575. Frameworks
    • There are many Perl web application frameworks
    • 576. Each creates applications in subtly different ways
    • 577. Hard to port applications between them
  • 578. The Goal
    • What if we had a specification that allowed us to easily move web applications between server architectures and frameworks
    • 579. PSGI is that specification
  • 580. PSGI Application
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 581. PSGI Application
    • A code reference
    • 582. Passed a reference to an environment hash
    • 583. Returns a reference to a three-element array
  • 586. A Code Reference
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 587. A Code Reference
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 588. Environment Hash
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 589. Environment Hash
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 590. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 591. Return Array Ref
    • my $app = sub { my $env = shift; return [ 200, [ ‘Content-Type’, ‘text/plain’ ], [ ‘Hello World’ ], ]; };
  • 592. Running PSGI App
    • Put code in app.psgi
    • 593. Drop in into a configured PSGI-aware web server
    • 594. Browse to URL
  • 595. PSGI-Aware Server
    • Plack contains a simple test server called plackup
    • 596. $ plackup app.psgi HTTP::Server::PSGI: Accepting connections at http://localhost:5000/
  • 597. Plack::Request
    • Plack::Request turns the environment into a request object
    • 598. use Plack::Request; use Data::Dumper; my $app = sub { my $req = Plack::Request->new(shift); return [ 200, [ 'Content-type', 'text/plain' ], [ Dumper $req ], ]; }
  • 599. Plack::Response
    • Plack::Response builds a PSGI response object
    • 600. use Plack::Request; use Plack::Response; use Data::Dumper; my $app = sub { my $req = Plack::Request->new(shift); my $res = Plack::Response->new(200); $res->content_type('text/plain'); $res->body(Dumper $req); return $res->finalize; }
  • 601. Middleware
    • Middleware wraps around an application
    • 602. Returns another PSGI application
    • 603. Simple spec makes this easy
    • 604. Plack::Middleware::*
    • 605. Plack::Builder adds middleware configuration language
  • 606. Middleware Example
    • use Plack::Builder; use Plack::Middleware::Runtime; my $app = sub { my $env = shift; return [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world' ], ] }; builder { enable 'Runtime'; $app; }
  • 607. Middleware Example
    • $ HEAD http://localhost:5000 200 OK Date: Tue, 20 Jul 2010 20:25:52 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Tue, 20 Jul 2010 20:25:52 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000050
  • 608. Middleware Example
    • $ HEAD http://localhost:5000 200 OK Date: Tue, 20 Jul 2010 20:25:52 GMT Server: HTTP::Server::PSGI Content-Length: 11 Content-Type: text/plain Client-Date: Tue, 20 Jul 2010 20:25:52 GMT Client-Peer: 127.0.0.1:5000 Client-Response-Num: 1 X-Runtime: 0.000050
  • 609. Plack::App::*
    • Ready-made solutions for common situations
    • 610. Plack::App::CGIBin
      • Cgi-bin replacement
    • Plack::App::Directory
      • Serve files with directory index
    • Plack::App::URLMap
      • Map apps to different paths
  • 611. Plack::App::*
    • Many more bundled with Plack
    • 612. Configured using Plack::Builder
  • 613. Plack::App::CGIBin
    • use Plack::App::CGIBin; use Plack::Builder; my $app = Plack::App::CGIBin->new( root => '/var/www/cgi-bin' )->to_app; builder { mount '/cgi-bin' => $app; };
  • 614. Plack::App::Directory
    • use Plack::App::Directory; my $app = Plack::App::Directory->new( root => '/home/dave/Dropbox/psgi' )->to_app;
  • 615. Framework Support
    • Many modern Perl applications already support PSGI
    • 616. Catalyst, CGI::Application, Dancer, Jifty, Mason, Maypole, Mojolicious, Squatting, Web::Simple
    • 617. Many more
  • 618. Catalyst Support
    • Catalyst::Engine::PSGI
    • 619. use MyApp; MyApp->setup_engine('PSGI'); my $app = sub { MyApp->run(@_) };
    • 620. Also Catalyst::Helper::PSGI
    • 621. script/myapp_create.pl PSGI
  • 622. PSGI Server Support
    • Many new web servers support PSGI
    • 623. Starman, Starlet, Twiggy, Corona, HTTP::Server::Simple::PSGI
    • 624. Perlbal::Plugin::PSGI
  • 625. PSGI Server Support
  • 628. Plack::Handler::Apache2
    • <Location /psgi> SetHandler perl-script PerlResponseHandler Plack::Handler::Apache2 PerlSetVar psgi_app /path/to/app.psgi </Location>
  • 629. PSGI/Plack Summary
    • PSGI is a specification
    • 630. Plack is an implementation
    • 631. PSGI makes your life easier
    • 632. Most of the frameworks and server you use already support PSGI
    • 633. No excuse not to use it
  • 634. Further Information
    • perldoc PSGI
    • 635. perldoc Plack
    • 636. http://plackperl.org/
    • 637. http://blog.plackperl.org/
    • 638. http://github.com/miyagawa/Plack
    • 639. #plack on irc.perl.org
  • 640. Modern Perl Summary
    • Perl has changed a lot in the last five years
    • 641. Perl continues to grow and change
    • 642. Perl is not a “scripting language”
    • 643. Perl is a powerful and flexible programming language
    • 644. Perl is a great way to get your job done
  • 645. That's all folks
    • Any questions?