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

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality AssuranceInflectra
 

Recently uploaded (20)

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance[Webinar] SpiraTest - Setting New Standards in Quality Assurance
[Webinar] SpiraTest - Setting New Standards in Quality Assurance
 

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