Slideshow transcript
Slide 1: Perl Sucks! (and what to do about it)
Slide 2: 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”
Slide 3: What this talk is • What’s a few major annoyances with Perl • What we the humble programmer can do to work around them
Slide 5: ~/bin
Slide 6: scp ~/bin nethost:
Slide 7: ssh newhost
Slide 8: jabme -m ‘compile done’
Slide 9: Module “Jabber::Lite” not found
Slide 10: -bash: jabme: /usr/local/bin/ perl: bad interpreter: No such file or directory
Slide 11: My Scripts Need • A particular version of Perl • A set of Perl modules
Slide 12: PAR
Slide 13: #!/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\";
Slide 14: Make an executable • perl -MCPAN -e ‘install PAR::Packer’ • pp -o hellow hellow.pl • ...copy “hellow” to new computer • ./hellow Hello World
Slide 16: #!/usr/bin/perl use strict; use warnings; print \"Hello World\\n\";
Slide 18: Build our own Perl and ship the whole thing
Slide 19: 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
Slide 20: Tell it where to go • mkdir -p /User/mark/bin/perl5.8.8 • ./configure.gnu --prefix=/User/mark/bin/ perl5.8.8
Slide 21: Install it • make • make test • make install
Slide 22: We now have our own perl in ~/bin
Slide 23: We can install it’s own modules
Slide 24: ~/bin/perl5.8.8/bin/perl -MCPAN -e ‘install Template’
Slide 25: Problem: different paths • /home/mark/bin/myperl • /home/mfowler/bin/myperl • /home/nisuser/bin/myperl
Slide 26: mv ~/bin/perl5.8.8 whatever
Slide 27: whatever/bin/perl -e ‘use Storable’
Slide 28: 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.
Slide 29: 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.
Slide 30: 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.
Slide 31: bleed to the rescue
Slide 32: B E TA 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
Slide 33: B E TA Tell it where to go • mkdir -p /User/mark/bin/perl5.9.5 • ./Configure -Dusedevel -Dprefix=/User/ mark/bin/perl5.9.5 -Duserelocatableinc -d
Slide 34: B E TA Tell it where to go • mkdir -p /User/mark/bin/perl5.9.5 • ./Configure -Dusedevel -Dprefix=/User/ mark/bin/perl5.9.5 -Duserelocatableinc -d
Slide 35: B E TA Install it • make • make test • make install
Slide 36: B E TA mv ~/bin/perl5.9.5 whatever
Slide 37: B E TA whatever/bin/perl5.9.5 -e ‘use Storable’
Slide 38: Exception Handling
Slide 39: Java try { throw new NoCheeseException(“redo”); } catch (NoCheeseException e) { system.err.println(e.toString()); }
Slide 40: Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
Slide 41: Perl has SUCKY SYNTAX
Slide 42: Sins include:
Slide 43: Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
Slide 44: die “stop my program”;
Slide 45: die “some catchable exception”;
Slide 46: Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
Slide 47: eval “some code to be compiled”;
Slide 48: eval { # run some code to catch errors in };
Slide 49: Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
Slide 50: Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
Slide 51: We can fix it!
Slide 52: (still) Perl try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; };
Slide 53: try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; } catch AnotherError with { print STDERR “oops\\n”; };
Slide 54: try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; } catch AnotherError with { print STDERR “oops\\n”; };
Slide 55: try( sub { throw NoCheeseException “redo”; }, catch NoCheeseException with(sub { print STDERR $@; }, catch AnotherError with(sub { print STDERR “oops\\n”; })));
Slide 56: try( sub { throw NoCheeseException “redo”; }, catch NoCheeseException with(sub { print STDERR $@; }, catch AnotherError with(sub { print STDERR “oops\\n”; })));
Slide 57: try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( with(sub { print STDERR $@; }, AnotherError->catch( with(sub { print STDERR “oops\\n”; })))));
Slide 58: sub with (&;@) { return @_ }
Slide 59: try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( with(sub { print STDERR $@; }, AnotherError->catch( with(sub { print STDERR “oops\\n”; })))));
Slide 60: try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, AnotherError->catch( sub { print STDERR “oops\\n”; })));
Slide 61: package OurErrorSuperclass; sub catch { my $class = shift; my $action = shift; return +{ class => $class, action => $action }, @_; }
Slide 62: try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, AnotherError->catch( sub { print STDERR “oops\\n”; })));
Slide 63: try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, +{ class => “AnotherError”, action => sub { print STDERR “oops\\n” } }));
Slide 64: try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oops\\n” } });
Slide 65: try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oops\\n” } });
Slide 66: try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oops\\n” } });
Slide 67: try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oops\\n” } });
Slide 68: (still) Perl try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; };
Slide 69: sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; }; }
Slide 70: sub foo { eval { return “This doesn’t return from foo”; }; if ($@) { .... } }
Slide 71: sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; }; }
Slide 72: sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed; }
Slide 73: sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed; }
Slide 74: MyException NoDairyException NoSpreadException NoMilkException NoButterException NoMargException NoCheeseException NoEdamException NoStiltonException NoBrieException
Slide 75: 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);
Slide 76: 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; };
Slide 77: But it’s a scripting language!
Slide 78: Don’t you just love the Template Toolkit?
Slide 79: bash$ tpage [% FOR a = [1..5]; a; END %] ^D 12345 bash$
Slide 80: #!perl $whereami = “Vienna”; print “Hello $whereami!\\n”;
Slide 81: #!tpage [% whereami = “Vienna” -%] Hello [% whereami %]!
Slide 82: bash$ ./hellov.tp
Slide 83: bash$ ./hellov.tp -bash: ./hellov.tp: tpage: bad interpreter: No such file or directory
Slide 84: where bash finds the Executable code to #!tpage load into memory [% whereami = “Vienna” -%] Hello [% whereami %]!
Slide 85: bash$ cat tpage #!/usr/bin/perl -w use strict; use Template; use AppConfig; …
Slide 86: Two possible solutions
Slide 87: Method one: Abuse source filters
Slide 88: • “Source filters are a way to change your source code before perl gets to see it”
Slide 89: #!/usr/bin/perl use strict; use warnings; use EnableDebugging; # DEBUG printing stuff out print \"hi\\n\";
Slide 90: #!/usr/bin/perl use strict; use warnings; use EnableDebugging; ;print STDERR “DEBUG: printing stuff out\\n”; print \"hi\\n\";
Slide 91: package EnableDebugging; use Filter::Simple; FILTER { s{#\\s*DEBUG\\s+(.*)} {;print STDERR q<DEBUG: $1>, \"\\n\";}; }; 1;
Slide 92: package EnableDebugging; use Filter::Simple; FILTER { s{#\\s*DEBUG\\s+(.*)} {;print STDERR q<DEBUG: $1>, \"\\n\";}; }; 1;
Slide 93: package tpage; use Filter::Simple; FILTER { s{#\\s*DEBUG\\s+(.*)} {;print STDERR q<DEBUG: $1>, \"\\n\";}; }; 1;
Slide 94: package tpage; use Filter::Simple; FILTER { s{#\\s*DEBUG\\s+(.*)} {;print STDERR q<DEBUG: $1>, \"\\n\";}; }; 1;
Slide 95: package tpage; use Filter::Simple; FILTER { $template .= $_; $_ = “”; }; 1;
Slide 96: package tpage; use Filter::Simple; FILTER { $template .= $_; $_ = “”; }; END { use Template; Template->new->process(\\$template); }
Slide 97: #!/usr/bin/perl use tpage; [%- whereami = “Vienna” -%] Hello [% whereami %]!
Slide 98: 2. Build our own executable
Slide 99: #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(); }
Slide 100: ( stolen from “perldoc perlembed”)
Slide 101: #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(); }
Slide 102: #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(); }
Slide 103: cc -o hellow hellow.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
Slide 104: bash$ ./hellow o hai
Slide 105: #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(); }
Slide 106: #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(); }
Slide 107: #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(); }
Slide 108: #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(); }
Slide 109: #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(); }
Slide 110: cc -o mytt mytt.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
Slide 111: now Executable code to load into memory #!mytt [% whereami = “Vienna” -%] Hello [% whereami %]!
Slide 112: #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; “hellov.tp” 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(); }
Slide 113: #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; “hellov.tp” 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(); }
Slide 115: A LP H A We’ve already seen source filters
Slide 116: B E TA PPI • 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
Slide 117: A LP H A MAD
Slide 118: A LP H A ./configure.gnu --prefix=~/bin/perl595 -Dusedevel -Dmad=y make && make test && make install
Slide 119: A LP H A my $a = 1; my $b = 2; print $a + $b;
Slide 120: A LP H A PERL_XMLDUMP=\"foo.xml\" ./perl foo.pl
Slide 121: </op_nextstate> A LP <op_sassign seq=\"9 -> 10\" H flags=\"VOID,KIDS,STACKED\"> A <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> <madprops> </op_null> <op_nextstate seq=\"2 -> 3\" flags=\"VOID\" line=\"1\" package=\"main\"> <madprops> <mad_sv key=\";\" val=\";\"/> <mad_sv key=\"#;\" val=\"
\"/> </madprops> <mad_sv key=\"o\" val=\"=\"/> </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\"> <mad_sv key=\"_o\" val=\" \"/> <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> </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\" <op_const seq=\"7 -> 8\" flags=\"SCALAR\" line=\"2\" package=\"main\"> <madprops> <mad_sv key=\";\" val=\";\"/> <mad_sv key=\"#;\" val=\"
\"/> </madprops> </op_nextstate> <op_sassign seq=\"9 -> 10\" flags=\"VOID,KIDS,STACKED\"> <madprops> IV=\"2\"> <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> </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\"/> <mad_sv key=\"X\" val=\"2\"/> </madprops> </op_padsv> </op_sassign> <op_nextstate seq=\"10 -> 11\" flags=\"VOID\" line=\"3\" package=\"main\"> <madprops> <mad_sv key=\";\" val=\";\"/> <mad_sv key=\"_X\" val=\" \"/> <mad_sv key=\"_;\" val=\"\"/> <mad_sv key=\"#;\" val=\"
\"/> </madprops> </op_nextstate> <op_print seq=\"15 -> 16\" flags=\"SCALAR,KIDS\"> <madprops> <mad_sv key=\"o\" val=\"print\"/> </madprops> </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> </op_const> <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 seq=\"8 -> 9\" targ=\"2\" </op_padsv> </op_add> </op_print> <op_null seq=\"0 -> (16)\" flags=\"VOID\" /> </op_leave> flags=\"SCALAR,REF,MOD,SPECIAL\"
Slide 122: B::Generate • Can be used to create OP codes (i.e. compiled Perl code) directly from Perl
Slide 123: 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); }
Slide 124: optomize.pm • Can be used to manipulate the OP codes after they’ve loaded • Kinda like source filters for compiled bypecode
Slide 125: 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
Slide 127: A LP H A package main; use typesafety; # 'summary', 'debug'; my FooBar $foo; # establish type-checked variables my FooBar $bar; # FooBar is the base class of references $bar will hold my 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
Slide 128: A LP H A package main; use typesafety; # 'summary', 'debug'; my FooBar $foo; # establish type-checked variables my FooBar $bar; # FooBar is the base class of references $bar will hold my 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
Slide 129: A LP H A package main; use typesafety; # 'summary', 'debug'; my FooBar $foo; # establish type-checked variables my FooBar $bar; # FooBar is the base class of references $bar will hold my 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
Slide 130: A LP H A package main; use typesafety; # 'summary', 'debug'; my FooBar $foo; # establish type-checked variables my FooBar $bar; # FooBar is the base class of references $bar will hold my 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




Add a comment on Slide 1
If you have a SlideShare account, login to comment; else you can comment as a guest- Favorites & Groups
Showing 1-50 of 12 (more)