Quick Upload

Perl Sucks - and what to do about it

from 2shortplanks, 2 years ago Add as contact

16111 views | 7 comments | 9 favorites | 4 embeds (Stats)

(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...

Embed customize close
 

More Info

This slideshow is Public
CC Attribution-NoDerivs LicenseCC Attribution-NoDerivs License

Views: 16111 Comments: 7 Favorites: 9 Downloads: 434

View Details: 16084 on Slideshare
27 from embeds
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this slideshow as inappropriate.

If needed, use the feedback form to let us know more details.

Loading...
Flash Player 9 (or above) is needed to view slideshows. We have detected that you do not have it on your computer. To install it, go here.
Post to Twitter Post to Twitter
Share on Facebook Share on Facebook
Post to Blogger Post to Blogger
Myspace Hi5 Friendster Xanga LiveJournal Facebook Blogger Tagged Typepad Freewebs BlackPlanet gigya icons
« Prev Comments 1 - 7 of 7 Next »
  • guestf33611
    guestf33611 said 10 months Edit Delete

    How does the implementation of Exceptions::define() work on slide 76?

  • 2shortplanks
    2shortplanks said 2 years Edit Delete

    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 said 2 years Edit Delete

    Error.pm can be used for exceptions.

  • 2shortplanks
    2shortplanks said 2 years Edit Delete

    'But when it comes time to run one of the commands...'

  • 2shortplanks
    2shortplanks said 2 years Edit Delete

    'Normally I can just SCP the files from my home linux box to the new machine'

  • 2shortplanks
    2shortplanks said 2 years Edit Delete

    'So, I have a bunch of scripts in my home directory that I install on every machine'

  • 2shortplanks
    2shortplanks said 2 years Edit Delete

    Strictly speaking, use of the camel with Perl is trademark O'Reilly. Ooops. ORA, do you care?

Add a comment If you have a SlideShare account, login to comment; otherwise comment as a guest.

    Presentation Transcript

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