Perl Teach-In (part 2)
Upcoming SlideShare
Loading in...5
×
 

Perl Teach-In (part 2)

on

  • 8,314 views

Part two of the Perl Teach-In. This is a newer version of the talk as presented at YAPC::Europe in August 2008.

Part two of the Perl Teach-In. This is a newer version of the talk as presented at YAPC::Europe in August 2008.

Statistics

Views

Total Views
8,314
Views on SlideShare
8,295
Embed Views
19

Actions

Likes
6
Downloads
154
Comments
0

6 Embeds 19

http://thomas-fahle.blogspot.com 11
http://www.slideshare.net 3
http://thomas-fahle.blogspot.de 2
http://thomas-fahle.blogspot.co.at 1
http://thomas-fahle.blogspot.in 1
http://thomas-fahle.blogspot.co.uk 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Perl Teach-In (part 2) Perl Teach-In (part 2) Presentation Transcript

  • Perl Teach-In
      • A One Day Perl Tutorial
      • Dave Cross
      • Magnum Solutions Ltd
      • [email_address]
  • Object Oriented Perl
  • Object Oriented Perl
    • How to design objects
    • Design Patterns
    • Inside-Out Objects
    • Moose
  • What We Won't Cover
    • Writing objects in Perl
    • Assume you already know that
    • perldoc perlboot
    • Object Oriented Perl – Damian Conway
  • How To Design Objects
    • Designing Objects is hard - OO Barbie
    • Very few hard and fast rules
    • A few heuristics
    • A bit of experience
    • A bit of guesswork
  • Prototyping
    • Plan to throw one away; you will, anyhow - Fred Brooks (The Mythical Man Month)
    • You won't get it right first time
    • Unless you're very lucky
    • Make it easy to refactor your code
      • Unit tests
      • Source code control
  • Subclassing
    • A good class is easy to subclass
    • Two argument bless
    • sub new { my $class = shift; my $self = {}; return bless $self, $class; }
  • Constructor Tip
    • You'll often see code like this
    • sub new { my $thing = shift; my $class = ref $thing || $thing; return bless {}, $class; }
    • Don't do that
  • Confusing Methods
    • The previous constructor can be called as a class method or an instance method
      • my $obj = MyClass->new;
      • my $obj2 = $obj->new;
    • Potentially confusing
    • What does $obj->new do?
    • Clone?
  • Separate Methods
    • Class method creates a new, empty, object
    • sub new { my $class = shift; return bless {}, $class; }
  • Separate Methods
    • Instance method creates a copy of an object
    • sub clone { my $self = shift; # warning! simplified! Buggy! return bless { %$self }, ref $self; }
  • Multiple Constructors
    • In Perl an constructor is just a subroutine
    • new is not a keyword
    • You can have as many constructors as you want
    • They can be called whatever you want
      • But using new for the standard constructor is recommended
  • new is Not a Keyword
    • People coming from other languages often write
    • my $obj = new MyObject;
    • This is potentially dangerous
    • See "perldoc perlobj" for gory details
    • Most of the time it will be fine
    • But avoid it
    • my $obj = MyObject->new;
  • Overriding Methods
    • Subclasses are created so that methods can be overridden
      • Or so that new methods can be added
    • Make it as easy as possible to subclass your classes
    • Create many methods
  • Case Study
    • I needed to create a new graph type for GD::Graph
    • Waterfall graph
    • Based on bar chart
    • Subclassing GD::Graph::bars
  • Bar Chart
  • Waterfall Chart
  • Things to Override
    • Colour choosing
      • pick_data_clr
    • Legend drawing
      • ???
    • The author didn't envisage my use case
    • I ended up copying far too much code
  • Be Consistent
    • A good object design is consistent
    • Similar things act in similar ways
    • Good candidates for programming standards
    • Some examples
  • Accessor vs Mutator
    • Or "getter vs setter"
    • Some people like one method foo
      • Works out what to do based on parameters
    • Some people like get_foo and set_foo
    • Pick one and stick to it
  • Mutator Return Values
    • What does a mutator return?
      • The old value
      • The new value
      • The object
      • Nothing
    • Pick one and stick to it
  • Don't Always Subclass
    • Not all relationships are "isa_a"
    • Sometimes "has_a" is more appropriate
    • If you're connecting to a database
    • Don't subclass DBI
    • Have a DBI attribute
  • Design Patterns
    • Perl does have some design patterns
    • Some of them come from Design Patterns
    • Some are more "Perlish"
  • Factory Object
    • Call constructor on one class
    • Constructor works out what is the most appropriate class to use
    • Returns an object of the appropriate class
    • Often not the same class as the constructor was called on
    • E.g. DBI->connect
  • AudioFile::Info
    • There are many Perl modules for reading tags from MP3 files
      • MP3::ID3Lib
      • MP3::Info
      • MP3::Tag
    • And a couple for reading tags from Ogg Vorbis files
      • Ogg::Vorbis::Header
      • Ogg::Vorbis::Header::PurePerl
  • Using AudioFile::Info
    • AudioFile::Info simplifies reading tag information from audio files
    • One syntax across numerous modules
    • $song = AudioFile::Info->new('a_song.mp3'); print $song->title, ' - ', $song->artist;
    • $song2 = AudioFile::Info->new('a_song.ogg'); print $song2->title, ' - ', $song2->artist;
    • print ref $song; # AudioFile::Info::MP3::Tag
    • print ref $song2; # AudioFile::Info::Ogg::Vorbis::Header
  • AudioFile::Info->new
    • Works out which kind of file it has been given
    • Works out the best installed module to handle that kind of file
    • Loads the appropriate module
    • Calls the constructor
    • Returns the new object
  • Singleton Pattern
    • Highlander pattern
    • “ There can be only one”
    • Only ever one instance of the class
    • If an instance has been created then use that
    • Otherwise create new instance
  • Singleton Class
    • package MySingleton; my $single; sub new { my $class = shift; unless ($single) { $single = bless {}, $class; } return $single; }
  • More Design Patterns
    • See Perl Design Patterns Wiki
    • http://perldesignpatterns.com/
  • Inside-Out Objects
    • Standard Perl objects are usually based on hashes
    • bless { name => 'Dave', email => 'dave@dave.org.uk' }, 'Person';
    • Two problems
    • People can access attributes directly
    • People can add attributes easily
  • Accessing Attributes
    • $person->{name} = '';
    • Avoids any checks in the mutator method
    • sub set_name { my $self = shift; my $name = shift; croak "Name can't be empty" unless $name; $self->{name} = $name; }
  • Adding Attributes
    • No checks on adding entries to the hash
    • $person->{nick} = 'davorg';
    • Our class knows nothing about this attribute
    • No check on mistyped attributes
    • $person->{NAME} = 'dave';
  • Inside-Out Objects
    • Inside-out objects solve both of these problems
    • An object is no longer a hash containing attributes
    • Each attribute is a package variable
    • A hash
      • Key is unique identifier for object
      • Value is the attribute value for that object
  • Example
    • package Person; use strict; my %name; my %email; sub new { my $self = bless {}, shift; $name{$self} = shift; $email{$self} = shift; return $self; }
  • Example (cont)
    • sub get_name { my $self = shift; return $name{$self}; } sub set_name { my $self = shift; my $name = shift; croak "name cannot be empty" unless $name; $name{$self} = $name; }
  • How It Works
    • The object is still a hash reference
    • Still blessed into the correct class
    • But it contains no data
    • All data is stored in the lexical variable hashes
    • Hence the name - Inside-Out
  • Solving Problems
    • People can access attributes directly
      • Attributes are now stored in lexical variables
      • Only visible from within package
      • All access is through methods
    • People can add attributes easily
      • Attribute names are now the names of lexical variables
      • use strict ensures that variable names can't be mistyped
  • One Improvement
    • The object is still a blessed hash
    • But we never put anything into it
    • So it may as well be a blessed scalar
    • sub new { my $self = bless (my $dummy), shift; $name{$self} = shift; $email{$self} = shift; return $self; }
    • No anonymous scalars
  • One New Problem
    • When our objects go out of scope, the blessed scalar ceases to exist
    • But the values still exist in the attribute hashes
    • Need a DESTROY method
    • sub DESTROY { my $self = shift; delete $name{$self}; delete $email{$self}; }
  • More Stuff
    • Need to handle inheritance
    • Automation of inside-out objects
      • Class::Std
      • Class::InsideOut
      • Object::InsideOut
    • See also Perl Best Practices (Damian Conway)
  • Moose
    • A complete modern object system for Perl 5
    • Based on experiments with Perl 6 object model
    • Built on top of Class::MOP
      • MOP - Meta Object Protocol
      • Set of abstractions for components of an object system
      • Classes, Objects, Methods, Attributes
    • An example might help
  • 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); }
  • Understanding Moose
    • There's a lot going on here
    • use Moose
      • Loads Moose environment
      • Makes our class a subclass of Moose::Object
      • Turns on strict and warnings
  • Creating Attributes
    • has 'x' => (isa => 'Int', is => 'ro')
      • Creates an attribute called 'x'
      • Constrainted to be an integer
      • Read-only accessor
    • has 'y' => (isa => 'Int', is => 'rw')
  • Defining Methods
    • sub clear { my $self = shift; $self->{x} = 0; $self->y(0); }
    • Standard method syntax
    • Uses generated method to set y
    • Direct hash access for x
  • Subclassing
    • package Point3D; use Moose; extends 'Point'; has 'z' => (isa => 'Int'); after 'clear' => sub { my $self = shift; $self->{z} = 0; };
  • Subclasses
    • extends 'Point'
      • Similar to use base
      • Overwrites @ISA instead of appending
    • has 'z' => (isa = 'Int')
      • Adds new attribute 'z'
      • No accessor function - private attribute
  • Extending Methods
    • after 'clear' => sub { my $self = shift; $self->{z} = 0; };
    • New clear method for subclass
    • Called after method for superclass
    • Cleaner than $self->SUPER::clear()
  • Creating Objects
    • Moose classes are used just like any other Perl class
    • $point = Point->new(x => 1, y => 2);
    • $p3d = Point3D->new(x => 1, y => 2, z => 3);
  • More Moose
    • Only scratching the surface
    • Many more options
    • Moose is well worth investigating
    • perldoc Moose::Cookbook::*
  • Configuration Files
  • Configuration Files
    • Can you just add...?
    • Users are never satisfied
    • Always want something changed
    • Most users won't edit code
    • Most users can be trained to edit config files
    • Move as much as possible into config files
  • Configuration in Code
    • This is bad
    • #!/usr/bin/perl use strict; use warnings; ## Configuration my $debug = 0; my $email = 'dave@dave.org.uk'; my $output_file = 'output.txt'; ## DO NOT EDIT BEYOND THIS POINT
  • Why is This Bad?
    • Don't trust 'em
    • Something will get broken
    • Code doesn't match what is in source code control
    • Recipe for disaster
    • Don't do it
  • Windows INI Files
    • [debugging] debug=1 verbose=0
    • Most users will understand this
    • Provide them with a dry-run option
      • Tell them what would happen
    • Parse with Config::IniFiles
  • XML
    • <debugging> <debug>1</debug> <verbose>0</debug> </debugging>
    • or
    • <debugging debug=&quot;1&quot; verbose=&quot;0&quot; />
    • Too complicated
    • Parse with XML::Simple (or XML::LibXML / XML::XPath)
  • YAML
    • --- debugging: debug: 1 verbose: 0
    • Looks a bit like INI file
    • Human-readable
    • Still give them a dry-run option
    • Parse with YAML
  • Swiss Army Config Parser
    • Config::Auto
    • &quot;Magical config file parser&quot;
    • Guesses where your config file is
    • Guesses what format it is in
    • And usually gets it right
  • Other Places
    • Environment variables
    • Command line options
      • Parse with Getopt::Long
    • Need to establish an order of precedence
    • $debug = defined $opt{debug} ? $opt{debug} : defined $ENV{DEBUG} ? $ENV{DEBUG} : defined $conf{debug} ? $conf{debug} : 0;
  • Web 2.0 Perl
  • Web 2.0 Perl
    • Mashups
    • Data Feeds
    • APIs
    • Ajax
    • Don't need to be using Ruby on Rails
    • CPAN modules can help
  • Reading Web Feeds
    • A lot of data available as web feeds
    • RSS / Atom
    • But which version of RSS
    • RDF vs RSS
  • Parsing RSS
    • XML::RSS
    • use XML::RSS; my $rss = XML::RSS->new; $rss->parsefile('myfeed.rss'); foreach (@{$rss->{items}}) { print $_->{title}, &quot; &quot;; print $_->{link}, &quot;n&quot;; }
    • Supports RSS 0.9, 0.91, 1.0 and 2.0
    • Most of the versions you'll see in the wild
  • Parsing Atom
    • XML::Atom
    • use XML::Atom::Feed; my $atom = XML::Atom::Feed->new('myatom.xml'); foreach ($atom->entries) { print $_->title, &quot; &quot;; print $_->link, &quot; &quot;; }
    • Cleverer than XML::RSS
    • Handles things like autodiscovery
    • my @feeds = XML::Atom::Feed->find_feeds ('http://example.com/');
  • Parsing RSS and Atom
    • XML::Feed uses XML::RSS or XML::Atom as appropriate
    • Allows code to handle all web feeds.
    • use XML::Feed; my $feed = XML::Feed->parse('feed.xml'); print $feed->title; foreach ($feed->entries) { print $_->title; }
  • Parsing Broken Feeds
    • Not all XML feeds are valid XML
    • This is bad!
    • You should complain bitterly to the provider
    • But until it is fixed you can use XML::Liberal
      • Slightly badly named
      • What it parses isn't XML
  • Mashing Up Web Feeds
    • Plagger - Pluggable RSS/Atom Aggregator
    • Huge distribution, installs half of CPAN
    • Dozens of small plugins
    • Single program ( plagger )
    • YAML configuration file
  • Web Services APIs
    • Many web sites expose web services
    • REST, RPC, SOAP
    • HTTP request
    • Parse response
      • Usually XML
      • Or JSON
  • Web Services on CPAN
    • Many CPAN modules for handling web services
    • Wrappers around LWP or WWW::Mechanize
    • Parse response into data structures or objects
    • Make dealing with web services very easy
  • CPAN Examples
    • Net::Backpack
    • Net::Amazon::*
    • Flickr::API
    • Geo::Google
    • Geo::Coder::Yahoo
  • API Keys
    • Many of these sites will monitor the requests you make
    • Use an API key
    • Apply for the key on the web site
    • Use the key in every request you use
  • API Example: Flickr
    • Get details of photos
    • Details at http://www.flickr.com/services/api/
    • Many methods
    • Perl module gives low level access
    • Need to know the API pretty well
  • Flickr API
    • #!/usr/bin/perl use strict; use warnings; use Flickr::API; my $flickr = Flickr::API->new({ key => 'your key goes here' }); my $response = $flickr->execute_method( 'flickr.photos.getRecent', { per_page => 2 } ); print $response->content;
  • Flickr API Results
    • <?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?> <rsp stat=&quot;ok&quot;> <photos page=&quot;1&quot; pages=&quot;500&quot; perpage=&quot;2&quot; total=&quot;1000&quot;> <photo id=&quot;525440809&quot; owner=&quot;65666164@N00&quot; secret=&quot;3ab099b893&quot; server=&quot;223&quot; farm=&quot;1&quot; title=&quot;00760052&quot; ispublic=&quot;1&quot; isfriend=&quot;0&quot; isfamily=&quot;0&quot; /> <photo id=&quot;525440801&quot; owner=&quot;47391132@N00&quot; secret=&quot;d24451edc8&quot; server=&quot;1009&quot; farm=&quot;2&quot; title=&quot;041070 14 29B&quot; ispublic=&quot;1&quot; isfriend=&quot;0&quot; isfamily=&quot;0&quot; /> </photos> </rsp>
  • APIs Without CPAN
    • You might find an API that doesn't have a CPAN module
    • Easy to do it yourself
    • Read the API documentation
    • LWP / WWW::Mechanize
    • Parse the response
    • (Release to CPAN)
  • Ajax
    • You don't need to be using Ruby on Rails to use AJAX
    • AJAX is largely just Javascript
    • With a server-side application
    • Which can be written in Perl
  • Ajax on CPAN
    • CGI::Ajax
      • Creates AJAX code in your CGI program output
      • Similar to Ruby on Rails AJAX helpers
    • JSON
      • Perl module for creating JSON
      • Common format for AJAX data exchange
      • Serialised Javascript Objects
      • A lot like YAML
  • Further Information
  • Further Information
    • Some suggestions for places to go for further information
    • Web sites
    • Books
    • Magazines
    • Mailing lists
    • Conferences
  • Copenhagen Perl Mongers
    • http://copenhagen.pm.org/
    • Mailing list
    • Regular meetings
    • Nordic Perl Workshop
    • YAPC::Europe
    • Many other local Perl Monger groups
      • http://pm.org/
  • Web Sites
    • use Perl;
      • Perl news site
      • Also journals
    • perl.com
      • O'Reilly run site
      • High quality articles
  • Web Sites
    • Perl Monks
      • Best web site for Perl questions
      • Many Perl experts
    • The Perl directory
      • http://perl.org/
      • Lists of many Perl-related sites
  • Books
    • Some recent Perl books
    • Perl Best Practices - Damian Conway
    • Advanced Perl Programming - Simon Cozens
    • Perl Hacks - chromatic, Conway & Poe
    • Intermediate Perl - Schwartz, foy & Phoenix
    • Mastering Perl - brian d foy
  • More Books
    • Higher Order Perl - Mark-Jason Dominus
    • Minimal Perl - Tim Maher
    • Pro Perl Debugging - Richard Foley & Joe McMahon
    • Perl & LWP - Sean M Burke
      • Updated online edition
      • http://lwp.interglacial.com/
    • See http://books.perl.org/
  • Magazines
    • The Perl Review
      • http://www.theperlreview.com/
    • Randal's monthly columns
      • Linux Magazine
      • SysAdmin
  • Mailing Lists
    • Many mailing lists devoted to Perl topics
    • See http://lists.cpan.org/
  • Conferences
    • The Open Source Convention
      • Portland 21-25 July 2008
    • YAPC
      • Chicago 16-18 June 2008
      • Copenhagen 13-15 August 2008
      • Brazil, Asia, Israel, Australia
    • One-Day Perl Workshops
    • See http://yapc.org/
  • The End
    • That's all folks
    • Any questions?