• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Perl Teach-In (part 2)
 

Perl Teach-In (part 2)

on

  • 8,172 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,172
Views on SlideShare
8,154
Embed Views
18

Actions

Likes
6
Downloads
152
Comments
0

6 Embeds 18

http://thomas-fahle.blogspot.com 11
http://www.slideshare.net 3
http://thomas-fahle.blogspot.co.at 1
http://thomas-fahle.blogspot.in 1
http://thomas-fahle.blogspot.de 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?