0
Introducing Modern Perl Dave Cross Magnum Solutions Ltd [email_address]
Modern Perl <ul><li>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 </li></ul>
Modern Perl <ul><li>Keeping up to date with Perl
Surveying modern modules and techniques
A lot to cover
Only an overview
Plenty of pointers to more information </li></ul>
What We Will Cover <ul><li>Modern Core Perl
Template Toolkit
DateTime
DBIx::Class
TryCatch </li></ul>
What We Will Cover <ul><li>Moose
autodie
Catalyst
PSGI/Plack </li></ul>
Schedule <ul><li>10:00 Start
11:30 – 11:45 Coffee
13:00 – 14:00 Lunch
15:30 – 15:40 Coffee
18:00 End
18:00 Pre-Conference Meeting </li></ul>
Resources <ul><li>Slides available on-line </li><ul><li>http://mag-sol.com/train/yapc/2011 </li></ul><li>Also see Slidesha...
Modern Core Perl
Perl Releases <ul><li>Perl 5 has moved to a regular release cycle
Major release every year
Minor releases when required </li></ul>
Release Numbering <ul><li>Even major numbers are production releases </li><ul><li>5.10, 5.12, 5.14 </li></ul><li>Odd major...
Perl 5.10 <ul><li>Released 18 th  Dec 2007 </li><ul><li>Perl's 20 th  birthday </li></ul><li>Many new features
Well worth upgrading </li></ul>
New Features <ul><li>Defined-or operator
Switch operator
Smart matching
say()
Lexical $_ </li></ul>
New Features <ul><li>State variables
Stacked file tests
Regex improvements
Many more </li></ul>
Defined Or <ul><li>Boolean expressions “short-circuit”
$val = $val || $default;
$val ||= $default;
What if 0 is a valid value?
Need to check “definedness”
$val = defined $val   ? $val : $default;
$val = $default unless defined $val; </li></ul>
Defined Or <ul><li>The defined or operator makes this easier
$val = $val // $default;
A different slant on truth
Checks definedness
Shortcircuit version too
$val //= $value; </li></ul>
Switch Statement <ul><li>Switch.pm was added with Perl 5.8
Source filter
Parser limitations </li><ul><li>Regular expressions
eval </li></ul><li>5.10 introduces a build-in switch statement </li></ul>
Given ... When <ul><li>Switch is spelled “given”
Case is spelled “when”
Powerful matching syntax </li></ul>
Given Example <ul><li>given ($foo) {   when (/^abc/) { $abc = 1; }   when (/^def/) { $def = 1; }   when (/^xyz/) { $xyz = ...
New Keywords <ul><li>Four new keywords </li><ul><li>given
when
default
continue </li></ul></ul>
given <ul><li>given(EXPR)
Assigns the result of EXPR to $_ within the following block
Similar to  do { my $_ = EXPR; ... } </li></ul>
when <ul><li>when (EXPR)
Uses smart matching to compare $_ with EXPR
Equivalent to  when ($_ ~~ EXPR)
~~ is the new smart match operator
Compares two values and “does the right thing”  </li></ul>
default <ul><li>default defines a block that is executed if no when blocks match
default block is optional </li></ul>
continue <ul><li>continue keyword falls through to the next when block
Normal behaviour is to break out of given block once the first when condition is matched </li></ul>
continue <ul><li>given($foo) {   when (/x/)   { say '$foo contains an x';   continue }   when (/y/)   { say '$foo contains...
Smart Matching <ul><li>~~ is the new Smart Match operator
Different kinds of matches
Dependent on the types of the operands
See “perldoc perlsyn” for the full details
CAVEAT: Subject to change </li></ul>
Smart Match Examples <ul><li>$foo ~~ $bar; # == or cmp
@foo ~~ $bar; # array contains value
%foo ~~ $bar; # hash key exists
$foo ~~ qr{$bar}; # regex match
@foo ~~ @bar; # arrays are identical
%foo ~~ %bar; # hash keys match
Many more alternatives </li></ul>
say() <ul><li>say() is a new alternative to print()
Adds a new line at the end of each call
say($foo); # print $foo, “n”;
Two characters shorter than print
Less typing </li></ul>
Lexical $_ <ul><li>$_ is a package variable
Always exists in main package
Can lead to subtle bugs when not localised correctly
Can now use  my $_  to create a lexically scoped variable called $_ </li></ul>
State Variables <ul><li>Lexical variables disappear when their scope is destroyed
sub variables {   my $x;   say ++$x; } variables() for 1 .. 3; </li></ul>
State Variables <ul><li>State variables retain their value when their scope is destroyed
sub variables {   state $x;   say ++$x; } variables() for 1 .. 3;
Like static variables in C </li></ul>
Stacked File Tests <ul><li>People often think you can do this
-f -w -x $file
Previously you couldn't
Now you can
Equivalent to
-x $file && -w _ && -f _ </li></ul>
Regex Improvements <ul><li>Plenty of regular expression improvements
Named capture buffers
Possessive quantifiers
Relative backreferences
New escape sequences
Many more </li></ul>
Named Capture Buffers <ul><li>Variables $1, $2, etc change if the regex is altered
Named captures retain their names
(?<name> ... ) to define
Use new %+ hash to access them </li></ul>
Named Capture Example <ul><li>while (<DATA>) {   if (/(?<header>[ws]+)   :s+(?<value>.+)/x) {   print &quot;$+{header} -> ...
Possessive Quantifiers <ul><li>?+ ,  *+ ,  ++
Grab as much as they can
Never give it back
Finer control over backtracking
'aaaa' =~ /a++a/
Never matches </li></ul>
Relative Backreferences <ul><li>g{N}
More powerful version of  1 ,  2 , etc
g{1}  is the same as  1
g{-1}  is the last capture buffer
g{-2}  is the one before that </li></ul>
New Escape Sequences <ul><li>h  – Horizontal white space
v  – Vertical white space
Also  H  and  V </li></ul>
Accessing New Features <ul><li>Some new features would break backwards compatibility
They are therefore turned off by default
Turn them on with the  feature  pragma
use feature 'say';
use feature 'switch';
use feature 'state';
use feature ':5.10'; </li></ul>
Implicit Loading <ul><li>Two ways to automatically turn on 5.10 features
Require a high enough version of Perl
use 5.10.0; # Or higher
-E command line option
perl -e 'say “hello”'
perl -E 'say “hello”' </li></ul>
Perl 5.12 <ul><li>Released 12 April 2010 </li><ul><li>5.12.4 20 June 2011 </li></ul><li>Many new enhancements </li></ul>
5.12 Enhancements <ul><li>Smart match changes
New modules </li><ul><li>autodie
parent </li></ul></ul>
5.12 Enhancements <ul><li>package NAME VERSION syntax
... operator
Implicit strictures
Y2038 compliance </li></ul>
... Operator <ul><li>Called the “yada-yada” operator
Used to stand in for unwritten code
sub unimplemented {   ... }
Code compiles
Throws an “unimplemented” exception when run </li></ul>
package NAME VER <ul><li>Declare the version of a package in the package declaration
package My::Package 1.23;
Equivalent to
package My::Package; our $VERSION = 1.23; </li></ul>
Implicit Strictures <ul><li>Requiring a version of Perl greater than 5.11 implicitly turns on use strict
use 5.12.0;
Is equivalent to
use strict; use feature ':5.12'; </li></ul>
Y2038 Compliance <ul><li>Core time functions are now Y2038 compliant </li></ul>
Smart Match Changes <ul><li>Some changes to Smart Match operator
No longer commutative
See new table in perlsyn
CAVEAT: More changes coming </li></ul>
New Modules <ul><li>Some new modules in the standard distribution
autodie
parent </li><ul><li>Better version of base. </li></ul></ul>
Perl 5.14 <ul><li>Released 14 May 2011 </li><ul><li>5.14.1 16 June 2011 </li></ul><li>Many new enhancements
5.16 due spring 2012 </li></ul>
5.14 Enhancements <ul><li>Non-destructive substitution
Container functions accept references
Package block
New modules </li></ul>
Non-destructive substitution <ul><li>New /r option on s/// and tr///
Copies input
Acts on copy
Original unmodifed
$_ = 'cat'; $new = s/cat/dog/r'; # $_ remains 'cat' </li></ul>
Container functions accept references <ul><li>Array & hash functions used to require arrays or hashes </li><ul><li>push @a...
@keys = keys %hash </li></ul><li>Even if you have a reference </li><ul><li>push @$arrayref, $value
@keys = keys %$hashref </li></ul></ul>
Container functions accept references <ul><li>Array & hash functions now accept references </li><ul><li>push $array_ref, $...
@keys = keys $hash_ref </li></ul><li>Currently experimental </li></ul>
Package block <ul><li>Attach a code block to a package declaration
package MyPackage { ... }
Equivalent to
{ package MyPackage; ... }
Can also declare a version
package MyPackage 1.23 { ... } </li></ul>
New Modules <ul><li>Many modules for parsing META files
CPAN::Meta::YAML & JSON::PP
CPAN::Meta
CPAN::Meta::Spec & CPAN::Meta::History
Module::Metadata </li></ul>
New Modules <ul><li>Other new modules
CPAN::Meta::YAML & JSON::PP
CPAN::Meta
CPAN::Meta::Spec & CPAN::Meta::History
Upcoming SlideShare
Loading in...5
×

Introduction to Modern Perl

18,666

Published on

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

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
18,666
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
129
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "Introduction to Modern Perl"

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

    Clipping is a handy way to collect important slides you want to go back to later.

×