77

Click here to load reader

Readable Perl

Embed Size (px)

DESCRIPTION

People like to claim Perl is line noise, with its sigils and regular expressions. But a lot of the features that make it possible to write, yes, truly awful, unreadable Perl, also let you write clean, maintainable code too. * those $%&* sigils! * there\'s More Than One Way To Do It * strings and data structures * map, grep, first class functions * metaprogramming and the CPAN * modern Object Oriented programming with Moose

Citation preview

Page 1: Readable Perl

/;{}def/#{def}def/$_={/Times­Boldexchselectfont}#/_{  rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[­14..­1])x50;q} 0 "%};s/m[ou]|[­\dA­ln­z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)­31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print; sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::­| ::­| .­. :||­:: 0­| .­| ::||­| .:|­. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('­',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||­| .||­| :|||­| ::||­| ||­:: :|||­| .:|/;{}def/#{def}def/$_={/Times­Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup

Readable Perl

GeekUp Liverpool, Tuesday 27th May, 2008http://upcoming.yahoo.com/event/691199/

[email protected]

Page 2: Readable Perl

/;{}def/#{def}def/$_={/Times­Boldexchselectfont}#/_{  rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[­14..­1])x50;q} 0 "%};s/m[ou]|[­\dA­ln­z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)­31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print;                 sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::­| ::­| .­. :||­:: 0­| .­| ::||­| .:|­. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('­',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||­| .||­| :|||­| ::||­| ||­:: :|||­| .:|/;{}def/#{def}def/$_={/Times­Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup

It's possible for Perl programmers 

to write messy programs.

Page 3: Readable Perl

/;{}def/#{def}def/$_={/Times­Boldexchselectfont}#/_{  rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[­14..­1])x50;q} 0 "%};s/m[ou]|[­\dA­ln­z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)­31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print;                 sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::­| ::­| .­. :||­:: 0­| .­| ::||­| .:|­. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('­',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||­| .||­| :|||­| ::||­| ||­:: :|||­| .:|/;{}def/#{def}def/$_={/Times­Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup

It's possible for Perl programmers 

to write messy programs.

In case you hadn't 

noticed.

Page 4: Readable Perl

/;{}def/#{def}def/$_={/Times­Boldexchselectfont}#/_{  rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[­14..­1])x50;q} 0 "%};s/m[ou]|[­\dA­ln­z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)­31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print;                 sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::­| ::­| .­. :||­:: 0­| .­| ::||­| .:|­. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('­',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||­| .||­| :|||­| ::||­| ||­:: :|||­| .:|/;{}def/#{def}def/$_={/Times­Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup

It's possible for the programmer to make a mess of things.

It's possible for Perl programmers to write messy programs.

(In case you hadn't noticed.) It's also possible for Perl

programmers to write extremely clean, concise, and beautiful programs.

The very fact that it's possible to write messy programs in Perl is also whatmakes it possible to write programs

that are cleaner in Perl than they could ever be in a language that attempts to enforce cleanliness.

Larry Wall

Page 5: Readable Perl

/;{}def/#{def}def/$_={/Times­Boldexchselectfont}#/_{  rmoveto} #/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverseq(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %Tcharpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} popneg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[­14..­1])x50;q} 0 "%};s/m[ou]|[­\dA­ln­z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#%2?'':"$0;").'pop;')x(ord($1)­31).'$*'/gee;s/((.(\e\[.m)*|.){77})/$1\n/g;print;                 sub showpage {}@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print#:: ::­| ::­| .­. :||­:: 0­| .­| ::||­| .:|­. :||open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('­',$1)){$q=0;for(split){s/\|/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";#.: ::||­| .||­| :|||­| ::||­| ||­:: :|||­| .:|/;{}def/#{def}def/$_={/Times­Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup

It's possible for the programmer to make a mess of things.

It's possible for Perl programmers to write messy programs.

(In case you hadn't noticed.) It's also possible for Perl

programmers to write extremely clean, concise, and beautiful programs.

The very fact that it's possible to write messy programs in Perl is also whatmakes it possible to write programs

that are cleaner in Perl than they could ever be in a language that attempts to enforce cleanliness.

Larry Wall

Page 6: Readable Perl

Disclaimer

<<Your favourite language>> is probably very nice too

Every language makes different trade­offs with readability

This is (mainly) about Perl's

Page 7: Readable Perl

&$%@!

                      Sigils...

Page 8: Readable Perl

Hungarian Notation

$one

@many

%dictionary

Page 9: Readable Perl

Constructing Strings

In a VB­like syntax "First: " + first + " Last: " + last + vbCrLf + "Age: " + age

Page 10: Readable Perl

Constructing Strings

In Perl, with interpolation "First: $first Last: $last\nAge: $age"

Page 11: Readable Perl

Constructing Strings

In Perl, with interpolation "First: ${first} Last: ${last}\nAge: ${age}"

More template-like

Page 12: Readable Perl

Constructing Strings

In Perl, with interpolation "First: ${first} Last: ${last}\nAge: ${age}"

Don't like the “\n” ?

Page 13: Readable Perl

Constructing Strings

Perl has multiline strings And HERE-DOCs.

my $x = <<“STRING”;First: ${first} Last: ${last}Age: ${age}STRING

Page 14: Readable Perl

Constructing Strings

Embed quotes in other languages “Is this \“readable\”?” “Is this “”better“”?”

Page 15: Readable Perl

Constructing Strings

Embed quotes in Perl 'This is “readable”'

Page 16: Readable Perl

Constructing Strings

Embed quotes in Perl 'This is “readable”' “This isn't too bad either”

Page 17: Readable Perl

Constructing Strings

Embed quotes in Perl 'This is “readable”' “This isn't too bad either” q{ And isn't this “cool”? }

Page 18: Readable Perl

Constructing String Lists

my @list = ( “one”, “two”, “three” “, ... d'oh!

Page 19: Readable Perl

Constructing String Lists

my @list = qw( one two three four five six );

qw() separated lists are easier to write at least...

Page 20: Readable Perl

There's more than one way to do it

Page 21: Readable Perl

Conditionals

if ( $age < 18 ) { ...

if ( ! $age < 18 ) { ...

Page 22: Readable Perl

Conditionals

if ( $age < 18 ) { ...

unless ( $age < 18 ) { ...

Page 23: Readable Perl

Conditionals

if ( $age < 18 ) { ...

unless ( $age < 18 ) { ...

print “Over 18s only”if $age < 18;

Page 24: Readable Perl

Conditionals

if ( $age < 18 ) { ...

unless ( $age < 18 ) { ...

print “Over 18s only”if $age < 18;

print “Over 18s only”unless $age >= 18;

Page 25: Readable Perl

Synonyms

Functionality? Readability

Page 26: Readable Perl

Booleans

or

||

Page 27: Readable Perl

Booleans

or

||

Both mean same thing... But have different precedence 'or' has lowest precedence of any operator

Page 28: Readable Perl

Booleans

<<any expression>> or <<fail>>;

Page 29: Readable Perl

Booleans

<<any expression>> or <<fail>>;

open my $FILEHANDLE, '<', # for reading $filename or die “Couldn't open ${filename}: $!”;

Page 30: Readable Perl

The unspeakable horror... regexes

Page 31: Readable Perl

Regexes

Not just Perl Perl just handles them very well

Page 32: Readable Perl

Regexes

How do you break up a string?

Page 33: Readable Perl

Regexes

How do you break up a string? Hack at it with INSTR()

Page 34: Readable Perl

Regexes

How do you break up a string? Hack at it with INSTR() Regexes

Page 35: Readable Perl

Regexes

How do you break up a string? Hack at it with INSTR() Regexes Parser

Parse::RecDescent, HOP::Parser

Page 36: Readable Perl

Regexes

How do you break up a string? Hack at it with INSTR() Regexes Parser

Parse::RecDescent, HOP::Parser Data structure parser

XML (RSS/XPath etc.), MIME, iCal etc.

Page 37: Readable Perl

Regexes

How do you break up a string? Regexes often hit the sweet spot...

...but they can get ugly when they're not the right tool for the job

Page 38: Readable Perl

Regexes

Perl regexes are builtin No need to

Compile(),  .Excecute(),  iterate through MatchCollection objects...

Page 39: Readable Perl

Regexes

Perl regexes are builtin my ($first, $last) =

$name =~ /(\w+) (\w+)/;

Page 40: Readable Perl

Regexes

Perl regexes are builtin my ($first, $last) =

$name =~ /(\w+) (\w+)/;

Other languages use strings: “(\\w+) (\\w+)” “\”\\w+\””

Page 41: Readable Perl

Regexes

Perl regexes are builtin my ($first, $last) =

$name =~ /(\w+) (\w+)/;

Other languages use strings “(\\w+) (\\w+)” “\”\\w+\””

All Perl's quoting goodness $url =~ s{^http://} {};

Page 42: Readable Perl

Regexes

Complex regexes are hard to read?

Page 43: Readable Perl

Regexes

Complex regexes are hard to read? Comment!

$_ =~ m/^ # anchor at beginning of line The\ quick\ (\w+)\ fox # fox adjective \ (\w+)\ over # fox action verb \ the\ (\w+) dog # dog adjective (?: # whitespace-trimmed comment: \s* \# \s* # whitespace and comment (.*?) # captured comment text; # (non-greedy!) \s* # any trailing whitespace )? # this is all optional $ # end of line anchor /x; # allow whitespace

Page 44: Readable Perl

Regexes

Named capture in 5.10 /(?<first>\w+) (?<last>\w+)/

Page 45: Readable Perl

            Data Structures

Page 46: Readable Perl

Data Structures

Perl is: Dynamic expression­based

Page 47: Readable Perl

Data Structures

Perl is: Dynamic expression­based

Can declare most data­structures trivially at runtime.

Page 48: Readable Perl

Data Structures

Declare most data­structures trivially at runtime.

my $person = { name => { first => 'Fred', last => 'Bloggs', }, age => 12, hobbies => [qw/ origami windsurfing /], };

Page 49: Readable Perl

Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1

C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();

int[] b = Enumerable.Range (0, 10).ToArray()

Page 50: Readable Perl

Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1

C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();

int[] b = Enumerable.Range (0, 10).ToArray()

“Elegant”

Page 51: Readable Perl

Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1

C# with Linq int[] a = Enumerable.Repeat (-1, 10).ToArray();

int[] b = Enumerable.Range (0, 10).ToArray()

“Elegant” Perl:

my @a = (-1) x 10; my @b = (0..10);

Page 52: Readable Perl

Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1

C# with Linq is elegant compared to: int[10] b;for (i=0; i<10; i++) { b[i] = i;}

Page 53: Readable Perl

Data Structures http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/#Tip1

C# with Linq is elegant compared to: int[10] b;for (i=0; i<10; i++) { b[i] = i;}

This is really the functional vs. imperative debate

Page 54: Readable Perl

Functional Programming

Perl is not a functional programming language Borrows some functional features

Page 55: Readable Perl

Functional Programming

Filter @recent = grep {

$_->sent > ($today – ONE_DAY)}@emails;

Page 56: Readable Perl

Functional Programming

Transform @full_names = map {

“$_->{first} $_->{last”}@people;

Page 57: Readable Perl

Functional Programming

A handful of other functions... sort join

Page 58: Readable Perl

Functional Programming

...and modules use List::Util 'sum';print sum(1..10);

Page 59: Readable Perl

Functional Programming

...and first class functions sub double { return 2 * shift } sub triple { return 3 * shift } my %dispatch = (

double => \&double,triple => \&triple,

); my $result = $dispatch{$command}->( $input );

Page 60: Readable Perl

Functional Programming

...including anonymous functions my %dispatch = (

double => sub { 2 * shift },triple => sub { 3 * shift },

)

Page 61: Readable Perl

Functional Programming

...and syntactic sugar my @doubled = map { 2 * $_ } @nums;

Page 62: Readable Perl

First class functions

Enable metaprogramming (OK, there's eval too... if you really need it)

Page 63: Readable Perl

First class functions

Typical cached subroutine

sub my_query {    my ($self, %params) = @_;    my $cache = $self­>get_cache;    my $key = $self­>get_key( %params );    my $result;    return $result if $result = $cache­>get($key);    $result = $self­>expensive_operation(%params);    # additional processing    $cache­>set($key, $result, 20);    return $result;}

Page 64: Readable Perl

First class functions

Typical cached subroutine

sub my_query {    my ($self, %params) = @_;    

    my $result                = $self­>expensive_operation(%params);    # additional processing

    return $result;}

Page 65: Readable Perl

First class functions

Turn this second into the first my $cached_query =

cache(\&query, %params);

Optionally, install it in the symbol table *query = $cached_query;

Or add syntactic sugar! sub my_query :Cached(time=>20) {

my $result = $self->expensive_operation;# additional processing

return $result;}

Page 66: Readable Perl

Working hard so you don't have to

Page 67: Readable Perl

Caching module

Attribute::Cached Unreleased but see Memoize package table hackery

(manual, but see Class::MOP) Attribute parsing (using Attribute::Handlers)

Page 68: Readable Perl

Surprising fact

Perl programmers are (at best) obsessive about syntax and readable code

Page 69: Readable Perl

Moose

Page 70: Readable Perl

Møøse

Built on scary crack (Class::MOP) http://moose.perl.org/

http://www.iinteractive.com/moose/

Page 71: Readable Perl

Møøse

package Point; use Moose; # automatically turns on strict and warnings

has 'x' => (is => 'rw', isa => 'Int'); has 'y' => (is => 'rw', isa => 'Int');

sub clear { my $self = shift; $self->x(0); $self->y(0); }

Page 72: Readable Perl

Møøse

package Point3D; use Moose;

extends 'Point';

has 'z' => (is => 'rw', isa => 'Int');

after 'clear' => sub { my $self = shift; $self->z(0); };

Page 73: Readable Perl

Møøse

Not just syntactic sugar (Post)modern OO

composition with roles

Page 74: Readable Perl

Møøse - example

HTTP request class package Request; use Moose; use Moose::Util::TypeConstraints; use HTTP::Headers (); use Params::Coerce (); use URI ();

has 'base' => (is => 'rw', isa => 'Uri', coerce => 1); has 'uri' => (is => 'rw', isa => 'Uri', coerce => 1); has 'method' => (is => 'rw', isa => 'Str'); has 'protocol' => (is => 'rw', isa => 'Protocol'); has 'headers' => ( is => 'rw', isa => 'Header', coerce => 1, default => sub { HTTP::Headers->new } );

Page 75: Readable Perl

Møøse - example

Hey!  Types!

subtype 'Header' => as 'Object' => where { $_->isa('HTTP::Headers') };

subtype 'Protocol' => as Str => where { /^HTTP\/[0-9]\.[0-9]$/ };

subtype 'Uri' => as 'Object' => where { $_->isa('URI') };

Page 76: Readable Perl

Møøse - example

Coercions working to make using the code easier

coerce 'Uri' => from 'Object' => via { $_->isa('URI') ? $_ : Params::Coerce::coerce( 'URI', $_ ) } => from 'Str' => via { URI->new( $_, 'http' ) };

Page 77: Readable Perl

Thank you

References perl.com/pub/a/1999/03/pm.html

perl.com/pub/a/2004/01/16/regexps.html

igoro.com/archive/7­tricks­to­simplify­your­programs­with­linq/

moose.perl.org/

blog.timbunce.org/2008/03/08/perl­myths/

Pictures “Larry Wall” by Michael McCracken

flickr.com/photos/michaelmccracken/540924868/

Obfus (BooK, mjd, Les Peters)

“Donald Duck” (Disney)

“Screwdrivers” by ladyheart morguefile.com/archive/?display=134240&

“Horror Masks” by xeniamorguefile.com/archive/?display=93245&

“Swimming Duck" by Yael Lewenstein flickr.com/photos/yaellebel

“Moose” by steve took it flickr.com/photos/stevewall/290510690/