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

Top Related