Advertisement
Advertisement

More Related Content

Advertisement

The Essential Perl Hacker's Toolkit

  1. The Essential Perl Hacker's Toolkit Stephen R. Scaffidi stephen@scaffidi.net YAPC::NA 2012
  2. Thanks for coming!
  3. Contents Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  4. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  5. This is a talk about the essentials
  6. essential to...
  7. getting my job done
  8. getting my job done better
  9. getting my job done faster
  10. so I can go out and drink beer
  11. so I can go out and drink beer spend time posting on reddit
  12. so I can go out and drink beer spend time posting on reddit watching youtube
  13. so I can go out and drink beer spend time posting on reddit watching youtube DANCING WITH THE STARS
  14. the editor of the previous three slides has been sacked
  15. I <3 Task::Kensho
  16. This talk != Task::Kensho
  17. But it is essential
  18. So look it up: Task::Kensho
  19. my @essentials
  20. Modules and tools I depend on
  21. make my job easier
  22. make my code better
  23. easier to write
  24. easier to read
  25. easier to maintain
  26. fewer bugs
  27. because...
  28. this is the code I don't write
  29. I'm not that good.
  30. Neither are you*
  31. Neither are you* *with several exceptions, half of them probably leaving this room right now...
  32. Previous iterations of this talk...
  33. touchy-feely
  34. waxed poetic about community
  35. gushed about the CPAN
  36. but...
  37. there's simply no time
  38. too many modules
  39. too many modules (on the dance floor)
  40. I prefer Perl because of this variety
  41. No language is perfect
  42. but...
  43. Perl has the CPAN
  44. And the CPAN gives us many, many ways to improve Perl
  45. mst once said...
  46. Perl is my VM CPAN is my language
  47. so...
  48. let's learn about some of the best parts of this language we call the CPAN
  49. Allow me some hubris... for the next 40 minutes or so.
  50. Bring out the modules!
  51. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  52. strict warnings
  53. really?
  54. experience tells me the answer is yes.
  55. English
  56. Get English versions of Perl's “punctuation vars”
  57. use English qw( -no_match_vars );
  58. Examples $#@^ English $ $OUTPUT_RECORD_SEPARATOR $$ $PID $^O $OSNAME $+ $LAST_PAREN_MATCH $! $OS_ERROR $? $CHILD_ERROR
  59. perldoc perlvar
  60. autodie
  61. Does what it says on the tin...
  62. # overrides various built-ins... use autodie; # Now, they all succeed or die! open my $foo, '>', 'file.txt'; chdir 'foo/bar'; pipe my($baz), my($buh); readline $foo; print “Do you ever check for print errors???”;
  63. autodie is indispensable. Why write an “or die” clause after every open() when you no longer have to???
  64. Data::Dumper
  65. Better than print().
  66. Data::Dump::Streamer
  67. Better than Data::Dumper!
  68. List::Util
  69. List::Util List::MoreUtils
  70. List::Util List::MoreUtils Scalar::Util
  71. For those go to Steve Lembark's talk on Util modules tomorrow morning.
  72. parent
  73. Stop messing with @ISA
  74. # sets up @ISA for you use parent qw(Some::Base Other::Base);
  75. Clear and declarative!
  76. Try::Tiny
  77. Stop messing with eval {} for exception handling.
  78. use Try::Tiny; try { something_that_might_die(); } catch { handle_error($_); # note: not $@ } finally { clean_up(); };
  79. IO::All
  80. Maybe not essential
  81. But damn handy!
  82. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  83. Not just modules
  84. App::cpanminus
  85. A light-weight cpan client that understands local::lib
  86. App::Ack
  87. ack is better than grep
  88. Devel::NYTProf
  89. Hands-down, the best profiler for Perl
  90. Devel::Cover
  91. Tells you how well your tests cover your code
  92. Speaking of tests...
  93. prove
  94. use it to run your tests
  95. Lots of things under Test::
  96. Test::More and/or Test::Most
  97. Many, many others...
  98. Perl::Critic
  99. Make sure your code confirms to certain quality standards.
  100. You do use coding standards, right??
  101. Moose and/or Mouse / Moo / Any::Moose
  102. Stop writing your own OO layers
  103. Stop doing it inconsistently
  104. Stop messing up inheritance, destructors, accessors and all those little things that you have to write over and over and over again...
  105. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  106. File::Spec
  107. my $path = join '/', qw(foo bar baz)
  108. What if it runs on Windows? Or VMS? Or early MacOS? AcornOS? QNX?
  109. use File::Spec; my $correct_path = File::Spec->catdir qw(foo bar baz);
  110. use File::Spec::Functions qw(catdir); my $path = catdir qw(foo bar baz);
  111. Declarative and correct
  112. Lots of other functions, too: ● canonpath ● splitpath ● catfile ● splitdir ● rootdir ● catpath ● updir ● abs2rel ● devnull ● rel2abs ● tmpdir ● file_name_is_absolute ● curdir ● case_tolerant
  113. Path::Class
  114. use Path::Class qw(dir file); # create dir and file objects... my $dir = dir('foo', 'bar'); my $file = file('bob', 'file.txt'); # Stringifies with proper separator on # each supported platform print "dir: $dirn"; print "file: $filen"; # methods do what you expect... my $subdir = $dir->subdir('baz'); my $parent = $subdir->parent; my $dir2 = $file->dir;
  115. File::Find
  116. Traversing directories in a filesystem is tricky. You're not that good.
  117. File::Find::Rules
  118. If you don't like File::Find, File::Find::Rules has some very nice functionality. Try it.
  119. File::Touch
  120. For when you need to touch a file. Simple, and works cross- platform.
  121. File::Basename
  122. same as the system's basename and dirname commands.
  123. File::Slurp
  124. Simple thing... but which is more readable?
  125. my $text = do { local(@ARGV, $/) = "file.txt"; <> }; or my $text = read_file 'file.txt';
  126. File::ReadBackwards
  127. When you need it... you DON'T want to do it yourself!
  128. File::Temp
  129. Let this module handle temp files and directories for you and stop doing it wrong.
  130. File::HomeDir
  131. Don't try to find a user's home directory on your own.
  132. File::Which
  133. Why are you shelling out to which? STOP IT!
  134. File::Copy
  135. Don't shell out to the system. Don't write your own copy routine. Please, PLEASE, just use File::Copy.
  136. File::LibMagic and/or File::MimeInfo
  137. If you need to recognize a common file type... STOP DOING IT YOURSELF!!!
  138. If one doesn't work for you, try the other.
  139. File::Path
  140. recursively create and remove directories
  141. File::stat
  142. Can you remember this? my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat $file;
  143. Maybe this? my $dev = (stat $file)[0]; my $ino = (stat $file)[1]; my $mode = (stat $file)[2]; my $nlink = (stat $file)[3]; my $uid = (stat $file)[4]; my $gid = (stat $file)[5]; my $rdev = (stat $file)[6]; my $size = (stat $file)[7]; # etc...
  144. Try this, instead... use File::stat; my $s = stat $file; $s->dev; $s->ino; $s->size; Much nicer, no?
  145. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  146. Tie::IxHash or Tie::StoredOrderHash
  147. Building your own sucks
  148. Try this: use Tie::StoredOrderHash qw(ordered); my $hash = ordered [ one => 1, two => 2, three => 3 ]; while (my($k, $v) = each %$hash) { print "$k: $v "; } # one: 1 two: 2 three: 3
  149. Hash::Merge::Simple
  150. Recursively merge hash structures
  151. use Hash::Merge::Simple qw(merge); my $a = { a => 1, c => 3, d => { i => 2 }, r => {} }; my $b = { b => 2, a => 100, d => { l => 4 } }; my $c = merge $a, $b; # $c is now { # a => 100, b => 2, c => 3, # d => { i => 2, l => 4 }, r => {} }
  152. Simple, declarative and correct.
  153. Params::Util
  154. use Params::Util qw(_SCALAR _HASH _INSTANCE); sub foo { my $object = _INSTANCE(shift, 'Foo') or die; my $image = _SCALAR(shift) or die; my $opts = _HASHLIKE(shift) || {}; }
  155. Sure, it's ugly...
  156. But focused on correctly doing something common and (surprisingly) tricky
  157. Params::Validate
  158. The de-facto standard in parameter validation.
  159. Algorithm::Combinatorics
  160. Don't do combinatorics on your own. Your code will be wrong. It will be slow. It will suck.
  161. Set::CrossProduct or Set::CartesianProduct::Lazy
  162. Just here for shameless self- promotion.
  163. Data::Compare
  164. Recursively and correctly compare data structures.
  165. Test::Deep::NoTest
  166. More functionality than Data::Compare.
  167. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  168. DateTime
  169. The most correct handling of dates and times in Perl. Use it.
  170. DateTime::Format::Strptime and/or DateTime::Format::DateManip
  171. Use these to transform various time formats from strings into DateTime objects
  172. Time::Piece
  173. Make localtime() and gmtime() return objects... use Time::Piece; my $t = localtime; print "Time is $tn"; print "Year is ", $t->year, "n";
  174. Time::Local
  175. Gives you inverse functions for localtime() and gmtime() use Time::Local qw(timelocal timegm); my $localtime = timelocal( $sec, $min, $hour, $mday, $mon, $year); my $gmtime = timegm( $sec, $min, $hour, $mday, $mon, $year);
  176. DateTime::Tiny (and friends)
  177. If DateTime is too “heavy” for you, at least use DateTime::Tiny, or Date::Tiny or Time::Tiny
  178. Time::ParseDate
  179. Parsing dates and times is a PITA. Use a module... use Time::ParseDate qw(parsedate); $epoch_time = parsedate("12/11/94 2pm", %options)
  180. Date::Extract
  181. When you need to extract dates and times from arbitrary blocks of text...
  182. But it tries hard to avoid false- positives
  183. Date::Extract::Surprise
  184. For when you're willing to be surprised at the dates found!
  185. Simply works harder to find dates and times in text, at the cost of possibly false-positives.
  186. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  187. YAML::Any
  188. use YAML::Any qw(Dump Load); $YAML::Indent = 3; my $yaml = Dump(@objects); my @objects = Load($yaml);
  189. JSON
  190. use JSON qw(to_json from_json); my $json = to_json($perl_scalar); my $perl_scalar = from_json($json);
  191. Text::CSV
  192. use Text::CSV; my $csv = Text::CSV->new({ binary => 1 }); open my $fh, "<:encoding(utf8)", "test.csv"; while ( my $row = $csv->getline( $fh ) ) { $row->[2] =~ m/pattern/ or next; push @rows, $row; }
  193. URI URI::Split URI::Escape
  194. Spreadsheet::Read
  195. Parse and read in a bunch of different spreadsheet formats, including Excel.
  196. XML::Simple
  197. For simply reading in and parsing some XML into a data structure. For non-simple stuff, look at Task::Kensho!
  198. Check Task::Kensho for more XML essentials.
  199. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  200. Module::Runtime
  201. safely and properly load modules at run-time
  202. IO::Interactive
  203. Do you know how to properly test for an interactive terminal? DOUBTFUL
  204. IPC::Run
  205. The grand-daddy of running external commands and controlling the IO
  206. Capture::Tiny
  207. Capture stdout and stderr of any code
  208. It Just Plain Works(tm)
  209. Net::Server or Net::Daemon
  210. Writing daemons properly is hard
  211. String::ShellQuote
  212. (my $unsafe_string = q{string you're passing to system}) =~ s/([/;()])/$1/g
  213. Unsafe, incorrect, and ugly.
  214. use String::ShellQuote qw(shell_quote); my $safe_string = shell_quote q{something you might pass to system};
  215. Much safer and more correct
  216. IPC::System::Simple
  217. Make using system() and output capturing (a-la backticks) safer
  218. use IPC::System::Simple qw(system systemx); # overrides system() built-in... # Succeed or die, avoid shell if @args system("some_command",@args); # NEVER invokes the shell systemx("some_command",@args);
  219. use IPC::System::Simple qw(capture capturex); # Use capture() instead of backticks: (also works in list context) # Succeeds or dies, # avoids shell if @args my $output = capture("some_command",@args); # NEVER invokes the shell My $output = capturex("some_command",@args);
  220. Introduction The Little Things Slightly Bigger Things Handling Files and Filesystems Wrangling Data Structures and Types Dealing with Dates and Times Reading and Writing File Formats Potpourri Conclusion
  221. Don't take my word for it
  222. Explore the CPAN for yourself
  223. Create your own toolkit
  224. Be consistent
  225. be thoughtful
  226. Share what you learn
  227. Contribute and help this language grow!
  228. Thanks again. I'm hercynium on IRC and twitter.
Advertisement