perl sucks - and what to do about it

131
Perl Sucks! (and what to do about it)

Upload: 2shortplanks

Post on 10-May-2015

22.704 views

Category:

Technology


4 download

DESCRIPTION

(originally presented at YAPC::Europe::2007) No-one is as critical about something as those that love it dearly. Mark Fowler has been collecting complaints from professional Perl developers for years about what warts still remain with the language when strict and warnings are turned on. Are these problems unsolvable? A veteran Perl programmer himself Mark attempted to try and solve these issues - and then turned to the experts, the people who write books on Perl, the people who maintain the perl interpreter itself, for help. This is what he learned...

TRANSCRIPT

Page 1: Perl Sucks - and what to do about it

Perl Sucks!(and what to do about it)

Page 2: Perl Sucks - and what to do about it

What this talk is not

• “Wah, no one uses ‘use strict’”

• “People’s perception of Perl is wrong”

• “The CPAN/mailing list/a other website isn’t exactly how I like it”

• “The garbage collection de-allocation routine isn’t very efficent”

Page 3: Perl Sucks - and what to do about it

What this talk is

• What’s a few major annoyances with Perl

• What we the humble programmer can do to work around them

Page 4: Perl Sucks - and what to do about it
Page 5: Perl Sucks - and what to do about it

~/bin

Page 6: Perl Sucks - and what to do about it

scp ~/bin nethost:

Page 7: Perl Sucks - and what to do about it

ssh newhost

Page 8: Perl Sucks - and what to do about it

jabme -m ‘compile done’

Page 9: Perl Sucks - and what to do about it

Module “Jabber::Lite” not found

Page 10: Perl Sucks - and what to do about it

-bash: jabme: /usr/local/bin/perl: bad interpreter: No

such file or directory

Page 11: Perl Sucks - and what to do about it

My Scripts Need

• A particular version of Perl

• A set of Perl modules

Page 12: Perl Sucks - and what to do about it

PAR

Page 13: Perl Sucks - and what to do about it

#!/usr/bin/perl

use strict;use warnings;

use XML::LibXML;use Template;use DBD::SQLite;use CGI;use Parse::RecDescent;use List::MoreUtils;use Moose;

print "Hello World\n";

Page 14: Perl Sucks - and what to do about it

Make an executable

• perl -MCPAN -e ‘install PAR::Packer’

• pp -o hellow hellow.pl

• ...copy “hellow” to new computer

• ./hellow

Hello World

Page 15: Perl Sucks - and what to do about it
Page 16: Perl Sucks - and what to do about it

#!/usr/bin/perl

use strict;use warnings;

print "Hello World\n";

Page 17: Perl Sucks - and what to do about it
Page 18: Perl Sucks - and what to do about it

Build our own Perl and ship the whole thing

Page 19: Perl Sucks - and what to do about it

Get Stable Perl

• lwp-request $CPAN_URL > perl-5.8.8.tar.gz

• gunzip -c perl-5.8.8.tar.gz | tar -xvf -

• cd perl-5.8.8

Page 20: Perl Sucks - and what to do about it

Tell it where to go

• mkdir -p /User/mark/bin/perl5.8.8

• ./configure.gnu --prefix=/User/mark/bin/perl5.8.8

Page 21: Perl Sucks - and what to do about it

Install it

• make

• make test

• make install

Page 22: Perl Sucks - and what to do about it

We now have our own perl in ~/bin

Page 23: Perl Sucks - and what to do about it

We can install it’s own modules

Page 24: Perl Sucks - and what to do about it

~/bin/perl5.8.8/bin/perl -MCPAN -e ‘install

Template’

Page 25: Perl Sucks - and what to do about it

Problem: different paths

• /home/mark/bin/myperl

• /home/mfowler/bin/myperl

• /home/nisuser/bin/myperl

Page 26: Perl Sucks - and what to do about it

mv ~/bin/perl5.8.8whatever

Page 27: Perl Sucks - and what to do about it

whatever/bin/perl -e ‘use Storable’

Page 28: Perl Sucks - and what to do about it

Can't locate Storable.pm in @INC (@INC contains: /User/mark/bin/perl5.8.8/lib/5.8.8/darwin-2level /User/mark/bin/perl5.8.8/lib/5.8.8 /User/mark/bin/perl5.8.8/lib/site_perl/

5.8.8/darwin-2level /User/mark/bin/perl5.8.8/lib/site_perl/5.8.8 /User/mark/bin/perl5.8.8/lib/

site_perl .) at -e line 1.

Page 29: Perl Sucks - and what to do about it

Can't locate Storable.pm in @INC (@INC contains: /User/mark/bin/perl5.8.8/lib/5.8.8/darwin-2level /User/mark/bin/perl5.8.8/lib/5.8.8 /User/mark/bin/perl5.8.8/lib/site_perl/

5.8.8/darwin-2level /User/mark/bin/perl5.8.8/lib/site_perl/5.8.8 /User/mark/bin/perl5.8.8/lib/

site_perl .) at -e line 1.

Page 30: Perl Sucks - and what to do about it

Can't locate Storable.pm in @INC (@INC contains: ../lib/5.8.8/darwin-2level

../lib/5.8.8../lib/site_perl/5.8.8/darwin-2level

../lib/site_perl/5.8.8../lib/site_perl .) at -e line 1.

Page 31: Perl Sucks - and what to do about it

bleed to the rescue

Page 32: Perl Sucks - and what to do about it

Get Bleed Perl

• lwp-request $CPAN_URL > perl-5.9.5.tar.gz

• gunzip -c perl-5.9.5.tar.gz | tar -xvf -

• cd perl-5.9.5

BETA

Page 33: Perl Sucks - and what to do about it

Tell it where to go

• mkdir -p /User/mark/bin/perl5.9.5

• ./Configure -Dusedevel -Dprefix=/User/mark/bin/perl5.9.5 -Duserelocatableinc -d

BETA

Page 34: Perl Sucks - and what to do about it

Tell it where to go

• mkdir -p /User/mark/bin/perl5.9.5

• ./Configure -Dusedevel -Dprefix=/User/mark/bin/perl5.9.5 -Duserelocatableinc -d

BETA

Page 35: Perl Sucks - and what to do about it

Install it

• make

• make test

• make install

BETA

Page 36: Perl Sucks - and what to do about it

mv ~/bin/perl5.9.5whatever

BETA

Page 37: Perl Sucks - and what to do about it

whatever/bin/perl5.9.5 -e ‘use Storable’

BETA

Page 38: Perl Sucks - and what to do about it

Exception Handling

Page 39: Perl Sucks - and what to do about it

try { throw new NoCheeseException(“redo”);} catch (NoCheeseException e) { system.err.println(e.toString());}

Java

Page 40: Perl Sucks - and what to do about it

eval { die new NoCheeseError->new(“redo”);};if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@;} elsif ($@) { die $@ }

Perl

Page 41: Perl Sucks - and what to do about it

Perl has SUCKY SYNTAX

Page 42: Perl Sucks - and what to do about it

Sins include:

Page 43: Perl Sucks - and what to do about it

eval { die new NoCheeseError->new(“redo”);};if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@;} elsif ($@) { die $@ }

Perl

Page 44: Perl Sucks - and what to do about it

die “stop my program”;

Page 45: Perl Sucks - and what to do about it

die “some catchable exception”;

Page 46: Perl Sucks - and what to do about it

eval { die new NoCheeseError->new(“redo”);};if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@;} elsif ($@) { die $@ }

Perl

Page 47: Perl Sucks - and what to do about it

eval “some code to be compiled”;

Page 48: Perl Sucks - and what to do about it

eval { # run some code to catch errors in};

Page 49: Perl Sucks - and what to do about it

eval { die new NoCheeseError->new(“redo”);};if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@;} elsif ($@) { die $@ }

Perl

Page 50: Perl Sucks - and what to do about it

eval { die new NoCheeseError->new(“redo”);};if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@;} elsif ($@) { die $@ }

Perl

Page 51: Perl Sucks - and what to do about it

We can fix it!

Page 52: Perl Sucks - and what to do about it

try { throw NoCheeseException “redo”;}catch NoCheeseException with { print STDERR $@;};

(still) Perl

Page 53: Perl Sucks - and what to do about it

try { throw NoCheeseException “redo”;}catch NoCheeseException with { print STDERR $@;}catch AnotherError with { print STDERR “oops\n”;};

Page 54: Perl Sucks - and what to do about it

try { throw NoCheeseException “redo”;}catch NoCheeseException with { print STDERR $@;}catch AnotherError with { print STDERR “oops\n”;};

Page 55: Perl Sucks - and what to do about it

try( sub { throw NoCheeseException “redo”;},catch NoCheeseException with(sub { print STDERR $@;},catch AnotherError with(sub { print STDERR “oops\n”;})));

Page 56: Perl Sucks - and what to do about it

try( sub { throw NoCheeseException “redo”;},catch NoCheeseException with(sub { print STDERR $@;},catch AnotherError with(sub { print STDERR “oops\n”;})));

Page 57: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );},NoCheeseException->catch( with(sub { print STDERR $@;},AnotherError->catch( with(sub { print STDERR “oops\n”;})))));

Page 58: Perl Sucks - and what to do about it

sub with (&;@) { return @_}

Page 59: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );},NoCheeseException->catch( with(sub { print STDERR $@;},AnotherError->catch( with(sub { print STDERR “oops\n”;})))));

Page 60: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );},NoCheeseException->catch( sub { print STDERR $@;},AnotherError->catch( sub { print STDERR “oops\n”;})));

Page 61: Perl Sucks - and what to do about it

package OurErrorSuperclass;

sub catch { my $class = shift; my $action = shift; return +{ class => $class, action => $action }, @_;}

Page 62: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );},NoCheeseException->catch( sub { print STDERR $@;},AnotherError->catch( sub { print STDERR “oops\n”;})));

Page 63: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );}, NoCheeseException->catch( sub { print STDERR $@;}, +{ class => “AnotherError”, action => sub { print STDERR “oops\n” }}));

Page 64: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );}, +{ class => “NoCheeseException”, action => sub { print STDERR $@; }}, +{ class => “AnotherError”, action => sub { print STDERR “oops\n” }});

Page 65: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );}, +{ class => “NoCheeseException”, action => sub { print STDERR $@; }}, +{ class => “AnotherError”, action => sub { print STDERR “oops\n” }});

Page 66: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );}, +{ class => “NoCheeseException”, action => sub { print STDERR $@; }}, +{ class => “AnotherError”, action => sub { print STDERR “oops\n” }});

Page 67: Perl Sucks - and what to do about it

try( sub { NoCheeseException->throw( “redo” );}, +{ class => “NoCheeseException”, action => sub { print STDERR $@; }}, +{ class => “AnotherError”, action => sub { print STDERR “oops\n” }});

Page 68: Perl Sucks - and what to do about it

try { throw NoCheeseException “redo”;}catch NoCheeseException with { print STDERR $@;};

(still) Perl

Page 69: Perl Sucks - and what to do about it

sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; };}

Page 70: Perl Sucks - and what to do about it

sub foo { eval { return “This doesn’t return from foo”; }; if ($@) { .... }}

Page 71: Perl Sucks - and what to do about it

sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; };}

Page 72: Perl Sucks - and what to do about it

sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed;}

Page 73: Perl Sucks - and what to do about it

sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed;}

Page 74: Perl Sucks - and what to do about it

MyException

NoCheeseException

NoDairyException

NoMilkException

NoSpreadException

NoEdamException NoStiltonException NoBrieException

NoButterException

NoMargException

Page 75: Perl Sucks - and what to do about it

package NoDairyException;our @ISA = qw(MyError);

package NoMilkException;our @ISA = qw(NoDairyException);

package NoSpreadException;our @ISA = qw(NoDairyException);

package NoButterException;our @ISA = qw(NoSpreadException);

package NoMargException;our @ISA = qw(NoMargeException);

package NoCheeseException;our @ISA = qw(NoDairyException);

package NoEdamException;our @ISA = qw(NoCheeseException);

package NoStiltonException;our @ISA = qw(NoCheeseException);

package NoBrieException;our@ISA = qw(NoCheeseException);

Page 76: Perl Sucks - and what to do about it

Exceptions::define { exception NoDairyException; exception NoSpreadException extends NoDairyException; exception NoButterException extends NoSpreadException; exception NoMargException extends NoSpreadException; exception NoMilkException extends NoDairyException; exception NoCheeseException extends NoDairyException; exception NoEdamException extends NoCheeseException; exception NoStiltonException extends NoCheeseException; exception NoBrieException extends NoCheeseException;};

Page 77: Perl Sucks - and what to do about it

But it’s a scripting language!

Page 78: Perl Sucks - and what to do about it

Don’t you just love the Template Toolkit?

Page 79: Perl Sucks - and what to do about it

bash$ tpage[% FOR a = [1..5]; a; END %]^D12345bash$

Page 80: Perl Sucks - and what to do about it

#!perl

$whereami = “Vienna”;print “Hello $whereami!\n”;

Page 81: Perl Sucks - and what to do about it

#!tpage

[% whereami = “Vienna” -%]Hello [% whereami %]!

Page 82: Perl Sucks - and what to do about it

bash$ ./hellov.tp

Page 83: Perl Sucks - and what to do about it

bash$ ./hellov.tp -bash: ./hellov.tp: tpage: bad interpreter: No such file or directory

Page 84: Perl Sucks - and what to do about it

#!tpage

[% whereami = “Vienna” -%]Hello [% whereami %]!

where bash finds theExecutable code to

load into memory

Page 85: Perl Sucks - and what to do about it

bash$ cat tpage#!/usr/bin/perl -wuse strict;use Template;use AppConfig;…

Page 86: Perl Sucks - and what to do about it

Two possible solutions

Page 87: Perl Sucks - and what to do about it

Method one: Abuse source filters

Page 88: Perl Sucks - and what to do about it

• “Source filters are a way to change your source code before perl gets to see it”

Page 89: Perl Sucks - and what to do about it

#!/usr/bin/perl

use strict;use warnings;

use EnableDebugging;

# DEBUG printing stuff outprint "hi\n";

Page 90: Perl Sucks - and what to do about it

#!/usr/bin/perl

use strict;use warnings;

use EnableDebugging;

;print STDERR “DEBUG: printing stuff out\n”;print "hi\n";

Page 91: Perl Sucks - and what to do about it

package EnableDebugging;use Filter::Simple;

FILTER { s{#\s*DEBUG\s+(.*)} {;print STDERR q<DEBUG: $1>, "\n";};};

1;

Page 92: Perl Sucks - and what to do about it

package EnableDebugging;use Filter::Simple;

FILTER { s{#\s*DEBUG\s+(.*)} {;print STDERR q<DEBUG: $1>, "\n";};};

1;

Page 93: Perl Sucks - and what to do about it

package tpage;use Filter::Simple;

FILTER { s{#\s*DEBUG\s+(.*)} {;print STDERR q<DEBUG: $1>, "\n";};};

1;

Page 94: Perl Sucks - and what to do about it

package tpage;use Filter::Simple;

FILTER { s{#\s*DEBUG\s+(.*)} {;print STDERR q<DEBUG: $1>, "\n";};};

1;

Page 95: Perl Sucks - and what to do about it

package tpage;use Filter::Simple;

FILTER { $template .= $_; $_ = “”;};

1;

Page 96: Perl Sucks - and what to do about it

package tpage;use Filter::Simple;

FILTER { $template .= $_; $_ = “”;};

END { use Template; Template->new->process(\$template); }

Page 97: Perl Sucks - and what to do about it

#!/usr/bin/perluse tpage;

[%- whereami = “Vienna” -%]Hello [% whereami %]!

Page 98: Perl Sucks - and what to do about it

2. Build our own executable

Page 99: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" };

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq'oh hai\n’;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 100: Perl Sucks - and what to do about it

stolen from “perldoc perlembed”)(

Page 101: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" };

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq'o hai\n';", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 102: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" };

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq’o hai\n’;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 103: Perl Sucks - and what to do about it

cc -o hellow hellow.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

Page 104: Perl Sucks - and what to do about it

bash$ ./hellowo hai

Page 105: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" };

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq'o hai\n';", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 106: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0" };

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq’o hai\n’;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 107: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0", argv[0]};

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 4, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq’o hai\n’;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 108: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0", argv[0]};

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 4, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv("print qq’o hai\n’;", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 109: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0", argv[0]};

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 4, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv( “use Template \ Template->new->process($ARGV[0])", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

Page 110: Perl Sucks - and what to do about it

cc -o mytt mytt.c `perl -MExtUtils::Embed -e ccopts -e ldopts`

Page 111: Perl Sucks - and what to do about it

#!mytt

[% whereami = “Vienna” -%]Hello [% whereami %]!

now Executable code toload into memory

Page 112: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0", argv[0]};

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 4, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv( “use Template \ Template->new->process($ARGV[0])", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

“hellov.tp”

Page 113: Perl Sucks - and what to do about it

#include <EXTERN.h>#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env){ char *embedding[] = { "", "-e", "0", argv[0]};

PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl);

perl_parse(my_perl, NULL, 4, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl);

eval_pv( “use Template \ Template->new->process($ARGV[0])", TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM();}

“hellov.tp”

Page 114: Perl Sucks - and what to do about it
Page 115: Perl Sucks - and what to do about it

We’ve already seen source filters

ALPHA

Page 116: Perl Sucks - and what to do about it

• Pure Perl parser

• Only parses a subset of Perl

• Can’t tell the difference between certain Perl constructs

• This said - very very good at what it does

PPIBETA

Page 117: Perl Sucks - and what to do about it

MAD

ALPHA

Page 118: Perl Sucks - and what to do about it

./configure.gnu --prefix=~/bin/perl595 -Dusedevel -Dmad=y

make && make test && make install

ALPHA

Page 119: Perl Sucks - and what to do about it

my $a = 1;my $b = 2;

print $a + $b;

ALPHA

Page 120: Perl Sucks - and what to do about it

PERL_XMLDUMP="foo.xml" ./perl foo.pl

ALPHA

Page 121: Perl Sucks - and what to do about it

<op_leave seq="0 -> DONE" targ="1" flags="VOID,KIDS,PARENS" private="REFCOUNTED" refcnt="1"> <op_enter seq="1 -> 2" /> <op_null seq="0 -> (2)" flags="VOID"> <madprops> <mad_sv key=";" val=""/> </madprops> </op_null> <op_nextstate seq="2 -> 3" flags="VOID" line="1" package="main"> <madprops> <mad_sv key=";" val=";"/> <mad_sv key="#;" val="&#xA;"/> </madprops> </op_nextstate> <op_sassign seq="5 -> 6" flags="VOID,KIDS,STACKED"> <madprops> <mad_sv key="o" val="="/> <mad_sv key="_o" val=" "/> </madprops> <op_const seq="3 -> 4" flags="SCALAR" IV="1"> <madprops> <mad_sv key="X" val="1"/> <mad_sv key="_X" val=" "/> </madprops> </op_const> <op_padsv seq="4 -> 5" targ="1" flags="SCALAR,REF,MOD,SPECIAL" private="INTRO"> <madprops> <mad_sv key="$" val="$a"/> <mad_sv key="_$" val=" "/> <mad_sv key="d" val="my"/> <mad_sv key="_d" val=""/> </madprops> </op_padsv> </op_sassign> <op_nextstate seq="6 -> 7" flags="VOID" line="2" package="main"> <madprops> <mad_sv key=";" val=";"/> <mad_sv key="#;" val="&#xA;"/> </madprops> </op_nextstate> <op_sassign seq="9 -> 10" flags="VOID,KIDS,STACKED"> <madprops> <mad_sv key="o" val="="/> <mad_sv key="_o" val=" "/> </madprops> <op_const seq="7 -> 8" flags="SCALAR" IV="2"> <madprops> <mad_sv key="X" val="2"/> <mad_sv key="_X" val=" "/> </madprops> </op_const> <op_padsv seq="8 -> 9" targ="2" flags="SCALAR,REF,MOD,SPECIAL" private="INTRO"> <madprops> <mad_sv key="$" val="$b"/> <mad_sv key="_$" val=" "/> <mad_sv key="d" val="my"/> </madprops> </op_padsv> </op_sassign> <op_nextstate seq="10 -> 11" flags="VOID" line="3" package="main"> <madprops> <mad_sv key=";" val=";"/> <mad_sv key="_;" val=""/> <mad_sv key="#;" val="&#xA;"/> </madprops> </op_nextstate> <op_print seq="15 -> 16" flags="SCALAR,KIDS"> <madprops> <mad_sv key="o" val="print"/> </madprops> <op_pushmark seq="11 -> 12" flags="SCALAR" /> <op_add seq="14 -> 15" targ="3" flags="SCALAR,KIDS"> <madprops> <mad_sv key="o" val="+"/> <mad_sv key="_o" val=" "/> </madprops> <op_padsv seq="12 -> 13" targ="1" flags="SCALAR"> <madprops> <mad_sv key="$" val="$a"/> <mad_sv key="_$" val=" "/> </madprops> </op_padsv> <op_padsv seq="13 -> 14" targ="2" flags="SCALAR"> <madprops> <mad_sv key="$" val="$b"/> <mad_sv key="_$" val=" "/> </madprops> </op_padsv> </op_add> </op_print> <op_null seq="0 -> (16)" flags="VOID" /></op_leave>

<op_leave seq="0 -> DONE" targ="1" flags="VOID,KIDS,PARENS"

private="REFCOUNTED" refcnt="1">

<op_enter seq="1 -> 2" /> <op_null seq="0 -> (2)" flags="VOID">

<madprops> <mad_sv key=";" val=""/>

</madprops> </op_null>

<op_nextstate seq="2 -> 3" flags="VOID" line="1"

package="main"> <madprops>

<mad_sv key=";" val=";"/> <mad_sv key="#;" val="&#xA;"/>

</madprops> </op_nextstate>

<op_sassign seq="5 -> 6" flags="VOID,KIDS,STACKED">

<madprops> <mad_sv key="o" val="="/> <mad_sv key="_o" val=" "/>

</madprops> <op_const seq="3 -> 4" flags="SCALAR"

IV="1"> <madprops>

<mad_sv key="X" val="1"/> <mad_sv key="_X" val=" "/>

</madprops> </op_const>

<op_padsv seq="4 -> 5" targ="1" flags="SCALAR,REF,MOD,SPECIAL"

private="INTRO"> <madprops>

<mad_sv key="$" val="$a"/> <mad_sv key="_$" val=" "/>

<mad_sv key="d" val="my"/> <mad_sv key="_d" val=""/>

</madprops> </op_padsv>

</op_sassign> <op_nextstate seq="6 -> 7" flags="VOID"

line="2" package="main">

<madprops> <mad_sv key=";" val=";"/>

<mad_sv key="#;" val="&#xA;"/> </madprops> </op_nextstate>

<op_sassign seq="9 -> 10" flags="VOID,KIDS,STACKED">

<madprops> <mad_sv key="o" val="="/> <mad_sv key="_o" val=" "/>

</madprops> <op_const seq="7 -> 8" flags="SCALAR"

IV="2"> <madprops>

<mad_sv key="X" val="2"/> <mad_sv key="_X" val=" "/>

</madprops> </op_const>

<op_padsv seq="8 -> 9" targ="2" flags="SCALAR,REF,MOD,SPECIAL"

private="INTRO"> <madprops>

<mad_sv key="$" val="$b"/> <mad_sv key="_$" val=" "/>

<mad_sv key="d" val="my"/> </madprops>

</op_padsv> </op_sassign>

<op_nextstate seq="10 -> 11" flags="VOID" line="3"

package="main"> <madprops>

<mad_sv key=";" val=";"/> <mad_sv key="_;" val=""/>

<mad_sv key="#;" val="&#xA;"/> </madprops> </op_nextstate>

<op_print seq="15 -> 16" flags="SCALAR,KIDS"> <madprops>

<mad_sv key="o" val="print"/> </madprops>

<op_pushmark seq="11 -> 12" flags="SCALAR" /> <op_add seq="14 -> 15" targ="3"

flags="SCALAR,KIDS"> <madprops>

<mad_sv key="o" val="+"/> <mad_sv key="_o" val=" "/>

</madprops> <op_padsv seq="12 -> 13" targ="1"

flags="SCALAR"> <madprops>

<mad_sv key="$" val="$a"/> <mad_sv key="_$" val=" "/>

</madprops> </op_padsv>

<op_padsv seq="13 -> 14" targ="2" flags="SCALAR">

<madprops> <mad_sv key="$" val="$b"/> <mad_sv key="_$" val=" "/>

</madprops> </op_padsv>

</op_add> </op_print>

<op_null seq="0 -> (16)" flags="VOID" /></op_leave>

ALPHA

Page 122: Perl Sucks - and what to do about it

B::Generate

• Can be used to create OP codes (i.e. compiled Perl code) directly from Perl

Page 123: Perl Sucks - and what to do about it

use B::Generate; # Do nothing, slowly. CHECK { my $null = new B::OP("null",0); my $enter = new B::OP("enter",0); my $cop = new B::COP(0, "hiya", 0); my $leave = new B::LISTOP("leave", 0, $enter, $null); $leave->children(3); $enter->sibling($cop); $enter->next($cop); $cop->sibling($null); $null->next($leave); $cop->next($leave);

# Tell Perl where to find our tree. B::main_root($leave); B::main_start($enter); }

Page 124: Perl Sucks - and what to do about it

optomize.pm

• Can be used to manipulate the OP codes after they’ve loaded

• Kinda like source filters for compiled bypecode

Page 125: Perl Sucks - and what to do about it

Use?

• PPI is reliable, but limited in it’s ability

• Easy to try to do too much with

• Other techniques are very unstable / new

• B::Generate

• optomize

• MAD

Page 126: Perl Sucks - and what to do about it
Page 127: Perl Sucks - and what to do about it

package main;use typesafety; # 'summary', 'debug';

my FooBar $foo; # establish type-checked variablesmy FooBar $bar; # FooBar is the base class of references $bar will holdmy BazQux $baz;

$foo = new FooBar; # this is okay, because $foo holds FooBars$bar = $foo; # this is okay, because $bar also holds FooBars# $foo = 10; # this would throw an error - 10 is not a FooBar# $baz = $foo; # not allowed - FooBar isn't a BazQux$foo = $baz; # is allowed - BazQux is a FooBar because of inheritance$bar = $foo->foo($baz, 1); # this is okay, as FooBar::foo() returns FooBars also

typesafety::check(); # perform type check static analysis

ALPHA

Page 128: Perl Sucks - and what to do about it

package main;use typesafety; # 'summary', 'debug';

my FooBar $foo; # establish type-checked variablesmy FooBar $bar; # FooBar is the base class of references $bar will holdmy BazQux $baz;

$foo = new FooBar; # this is okay, because $foo holds FooBars$bar = $foo; # this is okay, because $bar also holds FooBars# $foo = 10; # this would throw an error - 10 is not a FooBar# $baz = $foo; # not allowed - FooBar isn't a BazQux$foo = $baz; # is allowed - BazQux is a FooBar because of inheritance$bar = $foo->foo($baz, 1); # this is okay, as FooBar::foo() returns FooBars also

typesafety::check(); # perform type check static analysis

ALPHA

Page 129: Perl Sucks - and what to do about it

package main;use typesafety; # 'summary', 'debug';

my FooBar $foo; # establish type-checked variablesmy FooBar $bar; # FooBar is the base class of references $bar will holdmy BazQux $baz;

$foo = new FooBar; # this is okay, because $foo holds FooBars$bar = $foo; # this is okay, because $bar also holds FooBars# $foo = 10; # this would throw an error - 10 is not a FooBar# $baz = $foo; # not allowed - FooBar isn't a BazQux$foo = $baz; # is allowed - BazQux is a FooBar because of inheritance$bar = $foo->foo($baz, 1); # this is okay, as FooBar::foo() returns FooBars also

typesafety::check(); # perform type check static analysis

ALPHA

Page 130: Perl Sucks - and what to do about it

package main;use typesafety; # 'summary', 'debug';

my FooBar $foo; # establish type-checked variablesmy FooBar $bar; # FooBar is the base class of references $bar will holdmy BazQux $baz;

$foo = new FooBar; # this is okay, because $foo holds FooBars$bar = $foo; # this is okay, because $bar also holds FooBars# $foo = 10; # this would throw an error - 10 is not a FooBar# $baz = $foo; # not allowed - FooBar isn't a BazQux$foo = $baz; # is allowed - BazQux is a FooBar because of inheritance$bar = $foo->foo($baz, 1); # this is okay, as FooBar::foo() returns FooBars also

typesafety::check(); # perform type check static analysis

ALPHA

Page 131: Perl Sucks - and what to do about it