SlideShare a Scribd company logo
1 of 131
Download to read offline
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”
What this talk is


• What’s a few major annoyances with Perl
• What we the humble programmer can do to
  work around them
~/bin
scp ~/bin nethost:
ssh newhost
jabme -m ‘compile done’
Module “Jabber::Lite”
    not found
-bash: jabme: /usr/local/bin/
 perl: bad interpreter: No
   such file or directory
My Scripts Need


• A particular version of Perl
• A set of Perl modules
PAR
#!/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 quot;Hello Worldnquot;;
Make an executable

• perl -MCPAN -e ‘install PAR::Packer’
• pp -o hellow hellow.pl
• ...copy “hellow” to new computer
• ./hellow
  Hello World
#!/usr/bin/perl

use strict;
use warnings;

print quot;Hello Worldnquot;;
Build our own Perl and
 ship the whole thing
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
Tell it where to go


• mkdir -p /User/mark/bin/perl5.8.8
• ./configure.gnu --prefix=/User/mark/bin/
  perl5.8.8
Install it

• make
• make test
• make install
We now have our own
    perl in ~/bin
We can install it’s own
     modules
~/bin/perl5.8.8/bin/perl
  -MCPAN -e ‘install
       Template’
Problem: different paths

• /home/mark/bin/myperl
• /home/mfowler/bin/myperl
• /home/nisuser/bin/myperl
mv ~/bin/perl5.8.8
    whatever
whatever/bin/perl -e
  ‘use Storable’
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.
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.
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.
bleed to the rescue
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
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
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
B
                               E
                                  TA
                 Install it

• make
• make test
• make install
B
                      E
                         TA




mv ~/bin/perl5.9.5
    whatever
B
                          E
                             TA




whatever/bin/perl5.9.5
  -e ‘use Storable’
Exception Handling
Java
try {
  throw new NoCheeseException(“redo”);
} catch (NoCheeseException e) {
  system.err.println(e.toString());
}
Perl
eval {
  die new NoCheeseError->new(“redo”);
};
if (blessed($@) &&
  $@->isa(“NoCheeseException”)) {
  print STDERR $@;
} elsif ($@) { die $@ }
Perl has SUCKY
   SYNTAX
Sins include:
Perl
eval {
  die new NoCheeseError->new(“redo”);
};
if (blessed($@) &&
  $@->isa(“NoCheeseException”)) {
  print STDERR $@;
} elsif ($@) { die $@ }
die “stop my program”;
die “some catchable exception”;
Perl
eval {
  die new NoCheeseError->new(“redo”);
};
if (blessed($@) &&
  $@->isa(“NoCheeseException”)) {
  print STDERR $@;
} elsif ($@) { die $@ }
eval “some code to be compiled”;
eval {
  # run some code to catch errors in
};
Perl
eval {
  die new NoCheeseError->new(“redo”);
};
if (blessed($@) &&
  $@->isa(“NoCheeseException”)) {
  print STDERR $@;
} elsif ($@) { die $@ }
Perl
eval {
  die new NoCheeseError->new(“redo”);
};
if (blessed($@) &&
  $@->isa(“NoCheeseException”)) {
  print STDERR $@;
} elsif ($@) { die $@ }
We can fix it!
(still) Perl
try {
  throw NoCheeseException “redo”;
}
catch NoCheeseException with {
   print STDERR $@;
};
try {
  throw NoCheeseException “redo”;
}
catch NoCheeseException with {
   print STDERR $@;
}
catch AnotherError with {
  print STDERR “oopsn”;
};
try {
  throw NoCheeseException “redo”;
}
catch NoCheeseException with {
   print STDERR $@;
}
catch AnotherError with {
  print STDERR “oopsn”;
};
try( sub {
   throw NoCheeseException “redo”;
},
catch NoCheeseException with(sub {
    print STDERR $@;
},
catch AnotherError with(sub {
   print STDERR “oopsn”;
})));
try( sub {
   throw NoCheeseException “redo”;
},
catch NoCheeseException with(sub {
    print STDERR $@;
},
catch AnotherError with(sub {
   print STDERR “oopsn”;
})));
try( sub {
   NoCheeseException->throw( “redo” );
},
NoCheeseException->catch( with(sub {
    print STDERR $@;
},
AnotherError->catch( with(sub {
   print STDERR “oopsn”;
})))));
sub with (&;@) {
  return @_
}
try( sub {
   NoCheeseException->throw( “redo” );
},
NoCheeseException->catch( with(sub {
    print STDERR $@;
},
AnotherError->catch( with(sub {
   print STDERR “oopsn”;
})))));
try( sub {
   NoCheeseException->throw( “redo” );
},
NoCheeseException->catch( sub {
    print STDERR $@;
},
AnotherError->catch( sub {
   print STDERR “oopsn”;
})));
package OurErrorSuperclass;

sub catch {
  my $class = shift;
  my $action = shift;
  return +{
    class => $class,
    action => $action
  }, @_;
}
try( sub {
   NoCheeseException->throw( “redo” );
},
NoCheeseException->catch( sub {
    print STDERR $@;
},
AnotherError->catch( sub {
   print STDERR “oopsn”;
})));
try( sub {
   NoCheeseException->throw( “redo” );
},
NoCheeseException->catch( sub {
    print STDERR $@;
}, +{
   class => “AnotherError”,
   action => sub { print STDERR “oopsn” }
}));
try( sub {
  NoCheeseException->throw( “redo” );
}, +{
  class => “NoCheeseException”,
  action => sub { print STDERR $@; }
}, +{
  class => “AnotherError”,
  action => sub { print STDERR “oopsn” }
});
try( sub {
  NoCheeseException->throw( “redo” );
}, +{
  class => “NoCheeseException”,
  action => sub { print STDERR $@; }
}, +{
  class => “AnotherError”,
  action => sub { print STDERR “oopsn” }
});
try( sub {
  NoCheeseException->throw( “redo” );
}, +{
  class => “NoCheeseException”,
  action => sub { print STDERR $@; }
}, +{
  class => “AnotherError”,
  action => sub { print STDERR “oopsn” }
});
try( sub {
  NoCheeseException->throw( “redo” );
}, +{
  class => “NoCheeseException”,
  action => sub { print STDERR $@; }
}, +{
  class => “AnotherError”,
  action => sub { print STDERR “oopsn” }
});
(still) Perl
try {
  throw NoCheeseException “redo”;
}
catch NoCheeseException with {
   print STDERR $@;
};
sub foo {
  try {
    return “This doesn’t return from foo”;
  }
  catch NoCheeseException with {
     print STDERR $@;
  };
}
sub foo {
  eval {
    return “This doesn’t return from foo”;
  };
  if ($@) { .... }
}
sub foo {
  try {
    return “This doesn’t return from foo”;
  }
  catch NoCheeseException with {
     print STDERR $@;
  };
}
sub foo {
  try {
    rreturn “This doesn’t return from foo”;
  }
  catch NoCheeseException with {
     print STDERR $@;
  } and return allowed;
}
sub foo {
  try {
    rreturn “This doesn’t return from foo”;
  }
  catch NoCheeseException with {
     print STDERR $@;
  } and return allowed;
}
MyException


      NoDairyException
                                            NoSpreadException


 NoMilkException
                             NoButterException

                                                 NoMargException

                       NoCheeseException


NoEdamException        NoStiltonException         NoBrieException
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);
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;
};
But it’s a scripting
    language!
Don’t you just love the
  Template Toolkit?
bash$ tpage
[% FOR a = [1..5]; a; END %]
^D
12345
bash$
#!perl

$whereami = “Vienna”;
print “Hello $whereami!n”;
#!tpage

[% whereami = “Vienna” -%]
Hello [% whereami %]!
bash$ ./hellov.tp
bash$ ./hellov.tp
-bash: ./hellov.tp: tpage: bad interpreter:
No such file or directory
where bash finds the
          Executable code to
#!tpage    load into memory


[% whereami = “Vienna” -%]
Hello [% whereami %]!
bash$ cat tpage
#!/usr/bin/perl -w
use strict;
use Template;
use AppConfig;
…
Two possible solutions
Method one:
Abuse source filters
• “Source filters are a way to change your
  source code before perl gets to see it”
#!/usr/bin/perl

use strict;
use warnings;

use EnableDebugging;

# DEBUG printing stuff out
print quot;hinquot;;
#!/usr/bin/perl

use strict;
use warnings;

use EnableDebugging;

;print STDERR “DEBUG: printing stuff outn”;
print quot;hinquot;;
package EnableDebugging;
use Filter::Simple;

FILTER {
  s{#s*DEBUGs+(.*)}
    {;print STDERR q<DEBUG: $1>, quot;nquot;;};
};

1;
package EnableDebugging;
use Filter::Simple;

FILTER {
  s{#s*DEBUGs+(.*)}
    {;print STDERR q<DEBUG: $1>, quot;nquot;;};
};

1;
package tpage;
use Filter::Simple;

FILTER {
  s{#s*DEBUGs+(.*)}
    {;print STDERR q<DEBUG: $1>, quot;nquot;;};
};

1;
package tpage;
use Filter::Simple;

FILTER {
  s{#s*DEBUGs+(.*)}
    {;print STDERR q<DEBUG: $1>, quot;nquot;;};
};

1;
package tpage;
use Filter::Simple;

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

1;
package tpage;
use Filter::Simple;

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

END {
  use Template;
  Template->new->process($template);
}
#!/usr/bin/perl
use tpage;

[%- whereami = “Vienna” -%]
Hello [% whereami %]!
2. Build our own
   executable
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

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

    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(quot;print qq'oh hain’;quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
(    stolen from
“perldoc perlembed”)
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

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

    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(quot;print qq'o hain';quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

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

    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(quot;print qq’o hain’;quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
cc -o hellow hellow.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
bash$ ./hellow
    o hai
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

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

    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(quot;print qq'o hain';quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

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

    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(quot;print qq’o hain’;quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
  char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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(quot;print qq’o hain’;quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
  char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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(quot;print qq’o hain’;quot;, TRUE);

    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

int main(int argc, char **argv, char **env)
{
  char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE);
    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
cc -o mytt mytt.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
now Executable code to
            load into memory
#!mytt

[% whereami = “Vienna” -%]
Hello [% whereami %]!
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

                                                   “hellov.tp”
int main(int argc, char **argv, char **env)
{
  char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE);
    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
#include <EXTERN.h>
#include <perl.h>

static PerlInterpreter *my_perl;

                                                   “hellov.tp”
int main(int argc, char **argv, char **env)
{
  char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE);
    perl_destruct(my_perl);
    perl_free(my_perl);
    PERL_SYS_TERM();
}
A
                      LP
                           H
                            A




We’ve already seen
  source filters
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
A
       LP
            H
             A




MAD
A
                                        LP
                                             H
                                              A



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

 make && make test && make install
A
                  LP
                       H
                        A




 my $a = 1;
 my $b = 2;
print $a + $b;
A
                                   LP
                                        H
                                         A




PERL_XMLDUMP=quot;foo.xmlquot; ./perl foo.pl
</op_nextstate>
                                                                                                   A
                                                                                                     LP
                                                                              <op_sassign seq=quot;9 -> 10quot;
                                                                                                        H
                                                                         flags=quot;VOID,KIDS,STACKEDquot;> A
<op_leave seq=quot;0 -> DONEquot; targ=quot;1quot; flags=quot;VOID,KIDS,PARENSquot;
     private=quot;REFCOUNTEDquot;
     refcnt=quot;1quot;>
  <op_enter seq=quot;1 -> 2quot; />
  <op_null seq=quot;0 -> (2)quot; flags=quot;VOIDquot;>
     <madprops>
        <mad_sv key=quot;;quot; val=quot;quot;/>
     </madprops>




                                                                                           <madprops>
  </op_null>
  <op_nextstate seq=quot;2 -> 3quot; flags=quot;VOIDquot;
        line=quot;1quot;
        package=quot;mainquot;>
     <madprops>
        <mad_sv key=quot;;quot; val=quot;;quot;/>
        <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/>
     </madprops>




                                                                             <mad_sv key=quot;oquot; val=quot;=quot;/>
  </op_nextstate>
  <op_sassign seq=quot;5 -> 6quot; flags=quot;VOID,KIDS,STACKEDquot;>
     <madprops>
        <mad_sv key=quot;oquot; val=quot;=quot;/>
        <mad_sv key=quot;_oquot; val=quot; quot;/>
     </madprops>
     <op_const seq=quot;3 -> 4quot; flags=quot;SCALARquot;
            IV=quot;1quot;>




                                                                            <mad_sv key=quot;_oquot; val=quot; quot;/>
        <madprops>
           <mad_sv key=quot;Xquot; val=quot;1quot;/>
           <mad_sv key=quot;_Xquot; val=quot; quot;/>
        </madprops>
     </op_const>
     <op_padsv seq=quot;4 -> 5quot; targ=quot;1quot; flags=quot;SCALAR,REF,MOD,SPECIALquot;
           private=quot;INTROquot;>
        <madprops>




                                                                                           </madprops>
           <mad_sv key=quot;$quot; val=quot;$aquot;/>
           <mad_sv key=quot;_$quot; val=quot; quot;/>
           <mad_sv key=quot;dquot; val=quot;myquot;/>
           <mad_sv key=quot;_dquot; val=quot;quot;/>
        </madprops>
     </op_padsv>
  </op_sassign>
  <op_nextstate seq=quot;6 -> 7quot; flags=quot;VOIDquot;




                                                                 <op_const seq=quot;7 -> 8quot; flags=quot;SCALARquot;
        line=quot;2quot;
        package=quot;mainquot;>
     <madprops>
        <mad_sv key=quot;;quot; val=quot;;quot;/>
        <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/>
     </madprops>
  </op_nextstate>
  <op_sassign seq=quot;9 -> 10quot; flags=quot;VOID,KIDS,STACKEDquot;>
     <madprops>




                                                                                               IV=quot;2quot;>
        <mad_sv key=quot;oquot; val=quot;=quot;/>
        <mad_sv key=quot;_oquot; val=quot; quot;/>
     </madprops>
     <op_const seq=quot;7 -> 8quot; flags=quot;SCALARquot;
            IV=quot;2quot;>
        <madprops>
           <mad_sv key=quot;Xquot; val=quot;2quot;/>
           <mad_sv key=quot;_Xquot; val=quot; quot;/>




                                                                                           <madprops>
        </madprops>
     </op_const>
     <op_padsv seq=quot;8 -> 9quot; targ=quot;2quot; flags=quot;SCALAR,REF,MOD,SPECIALquot;
           private=quot;INTROquot;>
        <madprops>
           <mad_sv key=quot;$quot; val=quot;$bquot;/>
           <mad_sv key=quot;_$quot; val=quot; quot;/>
           <mad_sv key=quot;dquot; val=quot;myquot;/>




                                                                             <mad_sv key=quot;Xquot; val=quot;2quot;/>
        </madprops>
     </op_padsv>
  </op_sassign>
  <op_nextstate seq=quot;10 -> 11quot; flags=quot;VOIDquot;
        line=quot;3quot;
        package=quot;mainquot;>
     <madprops>
        <mad_sv key=quot;;quot; val=quot;;quot;/>




                                                                            <mad_sv key=quot;_Xquot; val=quot; quot;/>
        <mad_sv key=quot;_;quot; val=quot;quot;/>
        <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/>
     </madprops>
  </op_nextstate>
  <op_print seq=quot;15 -> 16quot; flags=quot;SCALAR,KIDSquot;>
     <madprops>
        <mad_sv key=quot;oquot; val=quot;printquot;/>
     </madprops>




                                                                                           </madprops>
     <op_pushmark seq=quot;11 -> 12quot; flags=quot;SCALARquot; />
     <op_add seq=quot;14 -> 15quot; targ=quot;3quot; flags=quot;SCALAR,KIDSquot;>
        <madprops>
           <mad_sv key=quot;oquot; val=quot;+quot;/>
           <mad_sv key=quot;_oquot; val=quot; quot;/>
        </madprops>
        <op_padsv seq=quot;12 -> 13quot; targ=quot;1quot; flags=quot;SCALARquot;>
           <madprops>




                                                                                           </op_const>
              <mad_sv key=quot;$quot; val=quot;$aquot;/>
              <mad_sv key=quot;_$quot; val=quot; quot;/>
           </madprops>
        </op_padsv>
        <op_padsv seq=quot;13 -> 14quot; targ=quot;2quot; flags=quot;SCALARquot;>
           <madprops>
              <mad_sv key=quot;$quot; val=quot;$bquot;/>
              <mad_sv key=quot;_$quot; val=quot; quot;/>
           </madprops>




                                                                       <op_padsv seq=quot;8 -> 9quot; targ=quot;2quot;
        </op_padsv>
     </op_add>
  </op_print>
  <op_null seq=quot;0 -> (16)quot; flags=quot;VOIDquot; />
</op_leave>




                                                                     flags=quot;SCALAR,REF,MOD,SPECIALquot;
B::Generate


• Can be used to create OP codes (i.e.
  compiled Perl code) directly from Perl
use B::Generate;
# Do nothing, slowly.
 CHECK {
  my $null = new B::OP(quot;nullquot;,0);
  my $enter = new B::OP(quot;enterquot;,0);
  my $cop = new B::COP(0, quot;hiyaquot;, 0);
  my $leave = new B::LISTOP(quot;leavequot;, 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);
 }
optomize.pm

• Can be used to manipulate the OP codes
  after they’ve loaded
• Kinda like source filters for compiled
  bypecode
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
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
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
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
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
Perl Sucks - and what to do about it

More Related Content

What's hot

Perl 5.28 new features
Perl 5.28 new featuresPerl 5.28 new features
Perl 5.28 new featuresbrian d foy
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & ToolsIan Barber
 
Programming JVM Bytecode
Programming JVM BytecodeProgramming JVM Bytecode
Programming JVM BytecodeJoe Kutner
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnitferca_sl
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)brian d foy
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst TipsJay Shirley
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Joseph Scott
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitmfrost503
 
Zen: Building Maintainable Catalyst Applications
Zen: Building Maintainable Catalyst ApplicationsZen: Building Maintainable Catalyst Applications
Zen: Building Maintainable Catalyst ApplicationsJay Shirley
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven DevelopmentAugusto Pascutti
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Contextlichtkind
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlHideaki Ohno
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trialbrian d foy
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLitecharsbar
 
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練Sheng-Hao Ma
 
Advanced modulinos
Advanced modulinosAdvanced modulinos
Advanced modulinosbrian d foy
 

What's hot (20)

Perl 5.28 new features
Perl 5.28 new featuresPerl 5.28 new features
Perl 5.28 new features
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
Programming JVM Bytecode
Programming JVM BytecodeProgramming JVM Bytecode
Programming JVM Bytecode
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6
 
Unit testing with PHPUnit
Unit testing with PHPUnitUnit testing with PHPUnit
Unit testing with PHPUnit
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
AssertJ quick introduction
AssertJ quick introductionAssertJ quick introduction
AssertJ quick introduction
 
Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)Learning Perl 6 (NPW 2007)
Learning Perl 6 (NPW 2007)
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst Tips
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )
 
Mocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnitMocking Dependencies in PHPUnit
Mocking Dependencies in PHPUnit
 
Perl IO
Perl IOPerl IO
Perl IO
 
Zen: Building Maintainable Catalyst Applications
Zen: Building Maintainable Catalyst ApplicationsZen: Building Maintainable Catalyst Applications
Zen: Building Maintainable Catalyst Applications
 
SfCon: Test Driven Development
SfCon: Test Driven DevelopmentSfCon: Test Driven Development
SfCon: Test Driven Development
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed Perl
 
Advanced modulinos trial
Advanced modulinos trialAdvanced modulinos trial
Advanced modulinos trial
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
 
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練
NTUSTxTDOH 資訊安全基礎工作坊 基礎逆向教育訓練
 
Advanced modulinos
Advanced modulinosAdvanced modulinos
Advanced modulinos
 

Similar to Perl Sucks - and what to do about it

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In PerlKang-min Liu
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationAttila Balazs
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongersbrian d foy
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
Whatsnew in-perl
Whatsnew in-perlWhatsnew in-perl
Whatsnew in-perldaoswald
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de RailsFabio Akita
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationWorkhorse Computing
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Lucas Witold Adamus
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developersStoyan Stefanov
 

Similar to Perl Sucks - and what to do about it (20)

Good Evils In Perl
Good Evils In PerlGood Evils In Perl
Good Evils In Perl
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.The $path to knowledge: What little it take to unit-test Perl.
The $path to knowledge: What little it take to unit-test Perl.
 
Modern Perl
Modern PerlModern Perl
Modern Perl
 
Perl Bag of Tricks - Baltimore Perl mongers
Perl Bag of Tricks  -  Baltimore Perl mongersPerl Bag of Tricks  -  Baltimore Perl mongers
Perl Bag of Tricks - Baltimore Perl mongers
 
Bag of tricks
Bag of tricksBag of tricks
Bag of tricks
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Perl basics for Pentesters
Perl basics for PentestersPerl basics for Pentesters
Perl basics for Pentesters
 
Perl Moderno
Perl ModernoPerl Moderno
Perl Moderno
 
Cleancode
CleancodeCleancode
Cleancode
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 
Whatsnew in-perl
Whatsnew in-perlWhatsnew in-perl
Whatsnew in-perl
 
Impacta - Show Day de Rails
Impacta - Show Day de RailsImpacta - Show Day de Rails
Impacta - Show Day de Rails
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
BSDM with BASH: Command Interpolation
BSDM with BASH: Command InterpolationBSDM with BASH: Command Interpolation
BSDM with BASH: Command Interpolation
 
Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?Why async and functional programming in PHP7 suck and how to get overr it?
Why async and functional programming in PHP7 suck and how to get overr it?
 
JavaScript for PHP developers
JavaScript for PHP developersJavaScript for PHP developers
JavaScript for PHP developers
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 

Recently uploaded

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 

Recently uploaded (20)

Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 

Perl Sucks - and what to do about it

  • 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.
  • 10. -bash: jabme: /usr/local/bin/ perl: bad interpreter: No such file or directory
  • 11. My Scripts Need • A particular version of Perl • A set of Perl modules
  • 12. PAR
  • 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 quot;Hello Worldnquot;;
  • 14. Make an executable • perl -MCPAN -e ‘install PAR::Packer’ • pp -o hellow hellow.pl • ...copy “hellow” to new computer • ./hellow Hello World
  • 15.
  • 17.
  • 18. Build our own Perl and ship the whole thing
  • 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
  • 20. Tell it where to go • mkdir -p /User/mark/bin/perl5.8.8 • ./configure.gnu --prefix=/User/mark/bin/ perl5.8.8
  • 21. Install it • make • make test • make install
  • 22. We now have our own perl in ~/bin
  • 23. We can install it’s own modules
  • 24. ~/bin/perl5.8.8/bin/perl -MCPAN -e ‘install Template’
  • 25. Problem: different paths • /home/mark/bin/myperl • /home/mfowler/bin/myperl • /home/nisuser/bin/myperl
  • 27. whatever/bin/perl -e ‘use Storable’
  • 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.
  • 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.
  • 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.
  • 31. bleed to the rescue
  • 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
  • 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
  • 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
  • 35. B E TA Install it • make • make test • make install
  • 36. B E TA mv ~/bin/perl5.9.5 whatever
  • 37. B E TA whatever/bin/perl5.9.5 -e ‘use Storable’
  • 39. Java try { throw new NoCheeseException(“redo”); } catch (NoCheeseException e) { system.err.println(e.toString()); }
  • 40. Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
  • 41. Perl has SUCKY SYNTAX
  • 43. Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
  • 44. die “stop my program”;
  • 45. die “some catchable exception”;
  • 46. Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
  • 47. eval “some code to be compiled”;
  • 48. eval { # run some code to catch errors in };
  • 49. Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
  • 50. Perl eval { die new NoCheeseError->new(“redo”); }; if (blessed($@) && $@->isa(“NoCheeseException”)) { print STDERR $@; } elsif ($@) { die $@ }
  • 52. (still) Perl try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; };
  • 53. try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; } catch AnotherError with { print STDERR “oopsn”; };
  • 54. try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; } catch AnotherError with { print STDERR “oopsn”; };
  • 55. try( sub { throw NoCheeseException “redo”; }, catch NoCheeseException with(sub { print STDERR $@; }, catch AnotherError with(sub { print STDERR “oopsn”; })));
  • 56. try( sub { throw NoCheeseException “redo”; }, catch NoCheeseException with(sub { print STDERR $@; }, catch AnotherError with(sub { print STDERR “oopsn”; })));
  • 57. try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( with(sub { print STDERR $@; }, AnotherError->catch( with(sub { print STDERR “oopsn”; })))));
  • 58. sub with (&;@) { return @_ }
  • 59. try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( with(sub { print STDERR $@; }, AnotherError->catch( with(sub { print STDERR “oopsn”; })))));
  • 60. try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, AnotherError->catch( sub { print STDERR “oopsn”; })));
  • 61. package OurErrorSuperclass; sub catch { my $class = shift; my $action = shift; return +{ class => $class, action => $action }, @_; }
  • 62. try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, AnotherError->catch( sub { print STDERR “oopsn”; })));
  • 63. try( sub { NoCheeseException->throw( “redo” ); }, NoCheeseException->catch( sub { print STDERR $@; }, +{ class => “AnotherError”, action => sub { print STDERR “oopsn” } }));
  • 64. try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oopsn” } });
  • 65. try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oopsn” } });
  • 66. try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oopsn” } });
  • 67. try( sub { NoCheeseException->throw( “redo” ); }, +{ class => “NoCheeseException”, action => sub { print STDERR $@; } }, +{ class => “AnotherError”, action => sub { print STDERR “oopsn” } });
  • 68. (still) Perl try { throw NoCheeseException “redo”; } catch NoCheeseException with { print STDERR $@; };
  • 69. sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; }; }
  • 70. sub foo { eval { return “This doesn’t return from foo”; }; if ($@) { .... } }
  • 71. sub foo { try { return “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; }; }
  • 72. sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed; }
  • 73. sub foo { try { rreturn “This doesn’t return from foo”; } catch NoCheeseException with { print STDERR $@; } and return allowed; }
  • 74. MyException NoDairyException NoSpreadException NoMilkException NoButterException NoMargException NoCheeseException NoEdamException NoStiltonException NoBrieException
  • 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);
  • 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; };
  • 77. But it’s a scripting language!
  • 78. Don’t you just love the Template Toolkit?
  • 79. bash$ tpage [% FOR a = [1..5]; a; END %] ^D 12345 bash$
  • 80. #!perl $whereami = “Vienna”; print “Hello $whereami!n”;
  • 81. #!tpage [% whereami = “Vienna” -%] Hello [% whereami %]!
  • 83. bash$ ./hellov.tp -bash: ./hellov.tp: tpage: bad interpreter: No such file or directory
  • 84. where bash finds the Executable code to #!tpage load into memory [% whereami = “Vienna” -%] Hello [% whereami %]!
  • 85. bash$ cat tpage #!/usr/bin/perl -w use strict; use Template; use AppConfig; …
  • 88. • “Source filters are a way to change your source code before perl gets to see it”
  • 89. #!/usr/bin/perl use strict; use warnings; use EnableDebugging; # DEBUG printing stuff out print quot;hinquot;;
  • 90. #!/usr/bin/perl use strict; use warnings; use EnableDebugging; ;print STDERR “DEBUG: printing stuff outn”; print quot;hinquot;;
  • 91. package EnableDebugging; use Filter::Simple; FILTER { s{#s*DEBUGs+(.*)} {;print STDERR q<DEBUG: $1>, quot;nquot;;}; }; 1;
  • 92. package EnableDebugging; use Filter::Simple; FILTER { s{#s*DEBUGs+(.*)} {;print STDERR q<DEBUG: $1>, quot;nquot;;}; }; 1;
  • 93. package tpage; use Filter::Simple; FILTER { s{#s*DEBUGs+(.*)} {;print STDERR q<DEBUG: $1>, quot;nquot;;}; }; 1;
  • 94. package tpage; use Filter::Simple; FILTER { s{#s*DEBUGs+(.*)} {;print STDERR q<DEBUG: $1>, quot;nquot;;}; }; 1;
  • 95. package tpage; use Filter::Simple; FILTER { $template .= $_; $_ = “”; }; 1;
  • 96. package tpage; use Filter::Simple; FILTER { $template .= $_; $_ = “”; }; END { use Template; Template->new->process($template); }
  • 97. #!/usr/bin/perl use tpage; [%- whereami = “Vienna” -%] Hello [% whereami %]!
  • 98. 2. Build our own executable
  • 99. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot; }; 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(quot;print qq'oh hain’;quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 100. ( stolen from “perldoc perlembed”)
  • 101. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot; }; 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(quot;print qq'o hain';quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 102. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot; }; 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(quot;print qq’o hain’;quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 103. cc -o hellow hellow.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
  • 104. bash$ ./hellow o hai
  • 105. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot; }; 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(quot;print qq'o hain';quot;, 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[] = { quot;quot;, quot;-equot;, quot;0quot; }; 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(quot;print qq’o hain’;quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 107. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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(quot;print qq’o hain’;quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 108. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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(quot;print qq’o hain’;quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 109. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 110. cc -o mytt mytt.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
  • 111. now Executable code to load into memory #!mytt [% whereami = “Vienna” -%] Hello [% whereami %]!
  • 112. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; “hellov.tp” int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 113. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; “hellov.tp” int main(int argc, char **argv, char **env) { char *embedding[] = { quot;quot;, quot;-equot;, quot;0quot;, 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])quot;, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
  • 114.
  • 115. A LP H A We’ve already seen source filters
  • 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
  • 117. A LP H A MAD
  • 118. A LP H A ./configure.gnu --prefix=~/bin/perl595 -Dusedevel -Dmad=y make && make test && make install
  • 119. A LP H A my $a = 1; my $b = 2; print $a + $b;
  • 120. A LP H A PERL_XMLDUMP=quot;foo.xmlquot; ./perl foo.pl
  • 121. </op_nextstate> A LP <op_sassign seq=quot;9 -> 10quot; H flags=quot;VOID,KIDS,STACKEDquot;> A <op_leave seq=quot;0 -> DONEquot; targ=quot;1quot; flags=quot;VOID,KIDS,PARENSquot; private=quot;REFCOUNTEDquot; refcnt=quot;1quot;> <op_enter seq=quot;1 -> 2quot; /> <op_null seq=quot;0 -> (2)quot; flags=quot;VOIDquot;> <madprops> <mad_sv key=quot;;quot; val=quot;quot;/> </madprops> <madprops> </op_null> <op_nextstate seq=quot;2 -> 3quot; flags=quot;VOIDquot; line=quot;1quot; package=quot;mainquot;> <madprops> <mad_sv key=quot;;quot; val=quot;;quot;/> <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/> </madprops> <mad_sv key=quot;oquot; val=quot;=quot;/> </op_nextstate> <op_sassign seq=quot;5 -> 6quot; flags=quot;VOID,KIDS,STACKEDquot;> <madprops> <mad_sv key=quot;oquot; val=quot;=quot;/> <mad_sv key=quot;_oquot; val=quot; quot;/> </madprops> <op_const seq=quot;3 -> 4quot; flags=quot;SCALARquot; IV=quot;1quot;> <mad_sv key=quot;_oquot; val=quot; quot;/> <madprops> <mad_sv key=quot;Xquot; val=quot;1quot;/> <mad_sv key=quot;_Xquot; val=quot; quot;/> </madprops> </op_const> <op_padsv seq=quot;4 -> 5quot; targ=quot;1quot; flags=quot;SCALAR,REF,MOD,SPECIALquot; private=quot;INTROquot;> <madprops> </madprops> <mad_sv key=quot;$quot; val=quot;$aquot;/> <mad_sv key=quot;_$quot; val=quot; quot;/> <mad_sv key=quot;dquot; val=quot;myquot;/> <mad_sv key=quot;_dquot; val=quot;quot;/> </madprops> </op_padsv> </op_sassign> <op_nextstate seq=quot;6 -> 7quot; flags=quot;VOIDquot; <op_const seq=quot;7 -> 8quot; flags=quot;SCALARquot; line=quot;2quot; package=quot;mainquot;> <madprops> <mad_sv key=quot;;quot; val=quot;;quot;/> <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/> </madprops> </op_nextstate> <op_sassign seq=quot;9 -> 10quot; flags=quot;VOID,KIDS,STACKEDquot;> <madprops> IV=quot;2quot;> <mad_sv key=quot;oquot; val=quot;=quot;/> <mad_sv key=quot;_oquot; val=quot; quot;/> </madprops> <op_const seq=quot;7 -> 8quot; flags=quot;SCALARquot; IV=quot;2quot;> <madprops> <mad_sv key=quot;Xquot; val=quot;2quot;/> <mad_sv key=quot;_Xquot; val=quot; quot;/> <madprops> </madprops> </op_const> <op_padsv seq=quot;8 -> 9quot; targ=quot;2quot; flags=quot;SCALAR,REF,MOD,SPECIALquot; private=quot;INTROquot;> <madprops> <mad_sv key=quot;$quot; val=quot;$bquot;/> <mad_sv key=quot;_$quot; val=quot; quot;/> <mad_sv key=quot;dquot; val=quot;myquot;/> <mad_sv key=quot;Xquot; val=quot;2quot;/> </madprops> </op_padsv> </op_sassign> <op_nextstate seq=quot;10 -> 11quot; flags=quot;VOIDquot; line=quot;3quot; package=quot;mainquot;> <madprops> <mad_sv key=quot;;quot; val=quot;;quot;/> <mad_sv key=quot;_Xquot; val=quot; quot;/> <mad_sv key=quot;_;quot; val=quot;quot;/> <mad_sv key=quot;#;quot; val=quot;&#xA;quot;/> </madprops> </op_nextstate> <op_print seq=quot;15 -> 16quot; flags=quot;SCALAR,KIDSquot;> <madprops> <mad_sv key=quot;oquot; val=quot;printquot;/> </madprops> </madprops> <op_pushmark seq=quot;11 -> 12quot; flags=quot;SCALARquot; /> <op_add seq=quot;14 -> 15quot; targ=quot;3quot; flags=quot;SCALAR,KIDSquot;> <madprops> <mad_sv key=quot;oquot; val=quot;+quot;/> <mad_sv key=quot;_oquot; val=quot; quot;/> </madprops> <op_padsv seq=quot;12 -> 13quot; targ=quot;1quot; flags=quot;SCALARquot;> <madprops> </op_const> <mad_sv key=quot;$quot; val=quot;$aquot;/> <mad_sv key=quot;_$quot; val=quot; quot;/> </madprops> </op_padsv> <op_padsv seq=quot;13 -> 14quot; targ=quot;2quot; flags=quot;SCALARquot;> <madprops> <mad_sv key=quot;$quot; val=quot;$bquot;/> <mad_sv key=quot;_$quot; val=quot; quot;/> </madprops> <op_padsv seq=quot;8 -> 9quot; targ=quot;2quot; </op_padsv> </op_add> </op_print> <op_null seq=quot;0 -> (16)quot; flags=quot;VOIDquot; /> </op_leave> flags=quot;SCALAR,REF,MOD,SPECIALquot;
  • 122. B::Generate • Can be used to create OP codes (i.e. compiled Perl code) directly from Perl
  • 123. use B::Generate; # Do nothing, slowly. CHECK { my $null = new B::OP(quot;nullquot;,0); my $enter = new B::OP(quot;enterquot;,0); my $cop = new B::COP(0, quot;hiyaquot;, 0); my $leave = new B::LISTOP(quot;leavequot;, 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); }
  • 124. optomize.pm • Can be used to manipulate the OP codes after they’ve loaded • Kinda like source filters for compiled bypecode
  • 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
  • 126.
  • 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
  • 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
  • 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
  • 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