Perl Sucks - and what to do about it

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

8 comments

Comments 1 - 8 of 8 previous next Post a comment

  • + guest46140c52 guest46140c52 6 months ago
    thank god perl doesn’t allow you to distinguish easily between '1' the integer and '1' the string. reading ruby code often requires you to figure out the difference between these two. thank god overriding doesn’t work too well and thank goodness it makes perl code understandable....
  • + guestf33611 guestf33611 2 years ago
    How does the implementation of Exceptions::define() work on slide 76?
  • + 2shortplanks 2shortplanks 3 years ago
    Error.pm indeed can be used for exceptions, and I did mention it in the talk (just not on the written slides.) You’ll note most of my syntax is the same as Error.pm’s too.
  • + chorny chorny 3 years ago
    Error.pm can be used for exceptions.
  • + 2shortplanks 2shortplanks 3 years ago
    'But when it comes time to run one of the commands...'
  • + 2shortplanks 2shortplanks 3 years ago
    'Normally I can just SCP the files from my home linux box to the new machine'
  • + 2shortplanks 2shortplanks 3 years ago
    'So, I have a bunch of scripts in my home directory that I install on every machine'
  • + 2shortplanks 2shortplanks 3 years ago
    Strictly speaking, use of the camel with Perl is trademark O’Reilly. Ooops. ORA, do you care?
Post a comment
Embed Video
Edit your comment Cancel

12 Favorites & 3 Groups

Perl Sucks - and what to do about it - Presentation Transcript

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

+ 2shortplanks2shortplanks, 3 years ago

custom

20857 views, 12 favs, 6 embeds more stats

(originally presented at YAPC::Europe::2007)

No- more

More info about this document

CC Attribution-NoDerivs LicenseCC Attribution-NoDerivs License

Go to text version

  • Total Views 20857
    • 20793 on SlideShare
    • 64 from embeds
  • Comments 8
  • Favorites 12
  • Downloads 469
Most viewed embeds
  • 30 views on http://blog.xwolf.de
  • 15 views on http://www.kt.rim.or.jp
  • 9 views on http://thomas-fahle.blogspot.com
  • 7 views on http://wp.monotechnology.com:8088
  • 2 views on http://www.filescon.com

more

All embeds
  • 30 views on http://blog.xwolf.de
  • 15 views on http://www.kt.rim.or.jp
  • 9 views on http://thomas-fahle.blogspot.com
  • 7 views on http://wp.monotechnology.com:8088
  • 2 views on http://www.filescon.com
  • 1 views on http://www.easyrapidshare.com

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories

Groups / Events