SlideShare a Scribd company logo
Source Filters
   in perl
 Belgian perl workshop 2010
   hendrik van belleghem
Source Filters
             in perl
                    Belgian perl workshop 2010
                      hendrik van belleghem




Spoiler warning: This talk might ruin the magic behind Acme::bleach and acme::buffy
Eh?
Eh?


• What are Source Filters?
Eh?


• What are Source Filters?
• Writing Source Filters
Eh?


• What are Source Filters?
• Writing Source Filters
• Magic revealed!
What are source filters?
What are source filters?


• Manipulate code during compile time
What are source filters?


• Manipulate code during compile time
• Modules loaded during compile time
What are source filters?


• Manipulate code during compile time
• Modules loaded during compile time
• Only works on main::
What are source filters?


• Manipulate code during compile time
• Modules loaded during compile time
• Only works on main::
• Only parses $0
Example
Acme::bleach
Example
Acme::bleach
  before       after




For *really* clean programs
Example
         Acme::bleach


Before
Example
           Acme::bleach


Before
#!/usr/bin/perl
use Acme::Bleach;
print “Hello World”;
Example
        Acme::bleach


After
Example
           Acme::bleach


After
#!/usr/bin/perl
use Acme::Bleach;
Example
           Acme::bleach


After
#!/usr/bin/perl
use Acme::Bleach;
Example
          Acme::bleach


• Live demo?
Writing source filters
Writing source filters

• Approaches:
Writing source filters

• Approaches:
   • Filter::Util::Call
Writing source filters

• Approaches:
   • Filter::Util::Call
   • Filter::Simple
Writing source filters

• Approaches:
   • Filter::Util::Call
   • Filter::Simple
   • From scratch
Writing source filters

• Approaches:
   • Filter::Util::Call
   • Filter::Simple
   • From scratch
• Our example: Line numbers
Writing source filters
Writing source filters

• Problem: Filter the code first
Writing source filters

• Problem: Filter the code first
   • Adding line numbers
Writing source filters

• Problem: Filter the code first
   • Adding line numbers
   • Bleaching (Acme::Bleach)
Writing source filters

• Problem: Filter the code first
   • Adding line numbers
   • Bleaching (Acme::Bleach)
   • Buffy’ing (Acme::Buffy)
Writing source filters

• Problem: Filter the code first
   • Adding line numbers
   • Bleaching (Acme::Bleach)
   • Buffy’ing (Acme::Buffy)
   • Encrypting (Filter::CBC)
Writing source filters

• Problem: Filter the code first
   • Adding line numbers
   • Bleaching (Acme::Bleach)
   • Buffy’ing (Acme::Buffy)
   • Encrypting (Filter::CBC)
• Problem: Don’t filter filtered code again
Filter::Util::Call
Filter::Util::Call


• Module by Paul Marquess
Filter::Util::Call


• Module by Paul Marquess
• Part of Perl core
Filter::Util::Call


• Module by Paul Marquess
• Part of Perl core
• Could be easier
Filter::Util::Call
    package MyFilter;
use Filter::Util::Call;

sub import
{ my ($type, @arguments) = @_ ;
  filter_add([ ]) ;
}

sub filter
{ my ($self) = @_ ;
  my ($status) ;
  $status = filter_read();
  #Do magic with $_ if $status > 0
  return $status;
}
1;
Filter::Util::Call
    package MyFilter;
use Filter::Util::Call;
                          import is called when module is “used”
sub import
{ my ($type, @arguments) = @_ ;
  filter_add([ ]) ;
}

sub filter
{ my ($self) = @_ ;
  my ($status) ;
  $status = filter_read();
  #Do magic with $_ if $status > 0
  return $status;
}
1;
Filter::Util::Call
package MyFilter;
use Filter::Util::Call;

sub import
{ my ($type, @arguments) = @_ ;
  filter_add([ ]) ;
}

sub filter
{ my ($self) = @_ ;
  my ($status) ;
  $status = filter_read();
  if ($status) { $_ =~ s/World/Belgian Perl Workshop/g; }
  return $status;
}
1; # Hello World -> Hello Belgian Perl Workshop
Filter::NumberLines
package Filter::NumberLines;
use Filter::Util::Call;

sub import
{ my ($type, @arguments) = @_ ;
  filter_add([ ]) ;
}

sub filter
{ my ($self) = @_ ;
  my ($status) ;
  $status = filter_read();
  if ($status) { $_ =~ s/^d+:t//gm; }
  return $status;
}
1;
Filter::NumberLines
Filter::NumberLines


• One Problem..
Filter::NumberLines


• One Problem..
• We have to add the line numbers manually
Filter::NumberLines


• One Problem..
• We have to add the line numbers manually
• Introducing auto-filtering code...
Filter::NumberLines



Add this at the bottom..
Filter::NumberLines
open(INFILE,"<$0") || die $!;
open(OUTFILE,">$0.bak") || die $!;
my $line = 0; my $no_go = 0; my $past_use = 0; $|++;
while(<INFILE>)
{ $line++;
   if ($past_use && /^d+:t/) { $no_go++; last; }
  if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; }
  if (/use Filter::NumberLines;/) { $past_use++; }
  print OUTFILE $_;
}
close(OUTFILE);
close (INFILE);
if (!$no_go)
{ unlink($0) || die $!; rename ("$0.bak",$0);
  exit;
}
else { unlink("$0.bak") || die $!; }
Filter::NumberLines



• Live demo?
Filter::Simple
Filter::Simple


• Module by Damian Conway
Filter::Simple


• Module by Damian Conway
• Part of Perl core
Filter::Simple


• Module by Damian Conway
• Part of Perl core
• Much easier than Filter::Util::Call
Filter::Simple


    package MyFilter;
use Filter::Simple;

FILTER { do_some_magic(); };

1;
Filter::NumberLines


package Filter::NumberLines::Simple;
use Filter::Simple;

FILTER { s/^d+:t//gm; }

1;
Filter::NumberLines
Filter::NumberLines


• One Problem..
Filter::NumberLines


• One Problem..
• We have to add the line numbers again
Filter::NumberLines


• One Problem..
• We have to add the line numbers again
• Introducing auto-filtering code...
Filter::NumberLines



Add this at the bottom..
Filter::NumberLines
open(INFILE,"<$0") || die $!;
open(OUTFILE,">$0.bak") || die $!;
my $line = 0; my $no_go = 0; my $past_use = 0; $|++;
while(<INFILE>)
{ $line++;
   if ($past_use && /^d+:t/) { $no_go++; last; }
  if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; }
  if (/use Filter::NumberLines::Simple;/) { $past_use++; }
  print OUTFILE $_;
}
close(OUTFILE);
close (INFILE);
if (!$no_go)
{ unlink($0) || die $!; rename ("$0.bak",$0);
  exit;
}
else { unlink("$0.bak") || die $!; }
Filter::NumberLines



• Live demo?
From Scratch
package Filter::NumberLines::Scratch;

sub scratch { local $_ = pop; s/^d+:t//gm; return $_; }
sub import
{ open 0 or print "Can't number '$0'n" and exit;
   my $line = 0; my $no_go = 0; my $past_use = 0; my $file;
   while(<0>)
   { $line++;
     if ($past_use && /^d+:t/) { $no_go++; $file = join "",$_,<0>; last; }
     if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; }
     if (/use Filter::NumberLines::Scratch;/) { { $past_use++; }
     $file .= $_;
   }
  if ($no_go)
  { do { eval scratch $file; exit; } }
  else { open 0, ">$0" or print "Cannot number '$0'n" and exit;
         print {0} $file and exit;
       }
}
1;
From Scratch



• Live demo?
From Scratch
From Scratch
          Easy
                 Bree
                     zy!
From Scratch
                      Easy
                             Bree
                                 zy!

• Filter code..
From Scratch
                      Easy
                             Bree
                                 zy!

• Filter code..
• and eval’uate it.
Magic Revealed
Acme::Bleach
Acme::Bleach
• Bleaches code
Acme::Bleach
• Bleaches code
   • Step 1: Convert code to bit stream
Acme::Bleach
• Bleaches code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into tabs (1) and spaces (0)
Acme::Bleach
• Bleaches code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into tabs (1) and spaces (0)
• Reverse to unbleach
Acme::Bleach
• Bleaches code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into tabs (1) and spaces (0)
• Reverse to unbleach
• Written by Damian Conway
Acme::Bleach
• Bleaches code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into tabs (1) and spaces (0)
• Reverse to unbleach
• Written by Damian Conway
   • from scratch
Acme::Bleach
Acme::Bleach
   package Acme::Bleach;

my $tie = " t"x8;

sub whiten { local $_ = unpack "b*", pop; tr/01/ t/; s/(.{9})/$1n/g; $tie.$_ }
sub brighten { local $_ = pop; s/^$tie|[^ t]//g; tr/ t/01/; pack "b*", $_ }
sub dirty { $_[0] =~ /S/ }
sub dress { $_[0] =~ /^$tie/ }
open 0 or print "Can't rebleach '$0'n" and exit;
(my $shirt = join "", <0>) =~ s/.*^s*uses+Acme::Bleachs*;n//sm;
local $SIG{__WARN__} = &dirty;
do { eval brighten $shirt; exit } unless dirty $shirt && not dress $shirt;
open 0, ">$0" or print "Cannot bleach '$0'n" and exit;
print {0} "use Acme::Bleach;n", whiten $shirt and exit;
Acme::Bleach



• Live demo?
Acme::Buffy
Acme::Buffy

• Buffies code
Acme::Buffy

• Buffies code
   • Step 1: Convert code to bit stream
Acme::Buffy

• Buffies code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into uppercase and
     lowercase letters from the word Buffy
Acme::Buffy

• Buffies code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into uppercase and
     lowercase letters from the word Buffy
• Written by Leon Brocard
Acme::Buffy

• Buffies code
   • Step 1: Convert code to bit stream
   • Step 2: Convert bits into uppercase and
     lowercase letters from the word Buffy
• Written by Leon Brocard
• Written from scratch
Acme::Buffy
Acme::Buffy
    my $horns = “BUffY bUFFY” x 2;
my $i = 0;

sub _slay {
   my $willow = unpack "b*", pop;
   my @buffy = ( 'b', 'u', 'f', 'f', 'y', ' ' );
   my @BUFFY = ( 'B', 'U', 'F', 'F', 'Y', "t" );
   my $demons = $horns;
   foreach ( split //, $willow ) {
      $demons .= $_ ? $BUFFY[$i] : $buffy[$i];
      $i++;
      $i = 0 if $i > 5;
   }
   return $demons;
}
sub _unslay {
   my $demons = pop;
   $demons =~ s/^$horns//g;
   my @willow;
   foreach ( split //, $demons ) {
      push @willow, /[buffy ]/ ? 0 : 1;
   }
   return pack "b*", join '', @willow;
}
Acme::Buffy
Acme::Buffy
      sub _evil {
    return $_[0] =~ /S/;
}

sub _punch {
   return $_[0] =~ /^$horns/;
}

sub import {
   open 0 or print "Can't rebuffy '$0'n" and exit;
   ( my $demon = join "", <0> ) =~ s/.*^s*uses+Acme::Buffys*;n//sm;
   local $SIG{__WARN__} = &evil;
   do { eval _unslay $demon; exit }
      unless _evil $demon and not _punch $demon;
   open my $fh, ">$0" or print "Cannot buffy '$0'n" and exit;
   print $fh "use Acme::Buffy;n", _slay $demon and exit;
   print "use Acme::Buffy;n", _slay $demon and exit;
   return;
}
"Grrr, arrrgh";
Acme::Buffy



• Live demo?
Filter::CBC
Filter::CBC
• Encrypts code using Crypt::CBC
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
 • Hardcoded or external algorithm & key phrase
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
 • Hardcoded or external algorithm & key phrase
• Pass parameters in use statement
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
 • Hardcoded or external algorithm & key phrase
• Pass parameters in use statement
• Based on Filter::Util::Call
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
 • Hardcoded or external algorithm & key phrase
• Pass parameters in use statement
• Based on Filter::Util::Call
• Written by uhm me
Filter::CBC
• Encrypts code using Crypt::CBC
• Can use any algorithm that uses CBC cipher
 • Hardcoded or external algorithm & key phrase
• Pass parameters in use statement
• Based on Filter::Util::Call
• Written by uhm me
use Filter::CBC "Rijndael","my secret key";
Filter::CBC
Filter::CBC
   my $blank = “This space is left blank intentionally”;

sub import
{ my ($type) = shift @_;
 my $algorithm = shift || "Rijndael";
 $algorithm = $Ciphers{uc $algorithm} || $algorithm;
 my $key = shift || $blank; my ($ref) = [ ];
 $cipher = Crypt::CBC->new(-key => $key,-cipher => $algorithm);
 if (defined $algorithm && defined $key)
 { open(F,"<$0") || die $!; flock(F,2); seek(F,0,0);
    my @CODE = (); my $past_use;
    while(<F>)
    { if (/^# $blank/ && !$past_use) { close(F); last; }
      if (/use Filter::CBC/) { push(@CODE,$_); $past_use++; next; }
      if (!$past_use) { push(@CODE,$_); }
   else
Filter::CBC
Filter::CBC
          { my $code = $_; local $/ = undef; $code .= <F>;
           splice(@CODE,-2,0,"# $blank");
           $code = $cipher->encrypt($code);
           open(OUTFILE,">$0.bak") || die $!;
           binmode(OUTFILE);
           print OUTFILE @CODE,$code;
           close(OUTFILE); close(F);
           unlink("$0") || die $!;
           rename ("$0.bak",$0) || die $!;
           exit;
         }
     }
    }
    filter_add(bless $ref) ;
}

sub filter
{ my ($self) = @_ ; my ($status); local $/ = undef;
  if (($status = filter_read()) > 0) { $_ = $cipher->decrypt($_); }
  return $status ;
}
1;
Questions?



• Time for bonus slides?
Switch
Switch
   use Switch;
switch ($val) {
   case 1            { print "number 1"; }
   case "a"           { print "string a"; }
   case [1..10,42] { print "number in list"; }
   case /w+/        { print "pattern"; }
else { print "previous case not true"; }
}
Switch
   use Switch;
switch ($val) {
   case 1            { print "number 1"; }
   case "a"           { print "string a"; }
   case [1..10,42] { print "number in list"; }
   case /w+/        { print "pattern"; }
else { print "previous case not true"; }
}

is turned into
Switch
   use Switch;
switch ($val) {
   case 1            { print "number 1"; }
   case "a"           { print "string a"; }
   case [1..10,42] { print "number in list"; }
   case /w+/        { print "pattern"; }
else { print "previous case not true"; }
}

is turned into
if ($var == 1) { print “number 1”; }
elsif ($var eq “a”) { print “string a”; }
elsif (grep /$var [1..10,42]) { print "number in list" }
elsif ($var=~ /w+/) { print “pattern”; }
else { print “previous case not true”; }
Acme::Pony
Ad

More Related Content

What's hot (20)

Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-C
Kazunobu Tasaka
 
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Romain Dorgueil
 
Learn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik CubeLearn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik Cube
Manoj Kumar
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Drupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the islandDrupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the island
Angela Byron
 
"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo
Yandex
 
Defensive Coding Crash Course Tutorial
Defensive Coding Crash Course TutorialDefensive Coding Crash Course Tutorial
Defensive Coding Crash Course Tutorial
Mark Niebergall
 
Xtext Webinar
Xtext WebinarXtext Webinar
Xtext Webinar
Heiko Behrens
 
Starting Out With PHP
Starting Out With PHPStarting Out With PHP
Starting Out With PHP
Mark Niebergall
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
James Titcumb
 
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Thoughtworks
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
vibrantuser
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Intro to PHP for Beginners
Intro to PHP for BeginnersIntro to PHP for Beginners
Intro to PHP for Beginners
mtlgirlgeeks
 
Intro to Perl and Bioperl
Intro to Perl and BioperlIntro to Perl and Bioperl
Intro to Perl and Bioperl
Bioinformatics and Computational Biosciences Branch
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
Francesco Usai
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
Nikita Popov
 
Fantom and Tales
Fantom and TalesFantom and Tales
Fantom and Tales
kaushik_sathupadi
 
Working with Cocoa and Objective-C
Working with Cocoa and Objective-CWorking with Cocoa and Objective-C
Working with Cocoa and Objective-C
Kazunobu Tasaka
 
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Simple ETL in Python 3.5+ - PolyConf Paris 2017 - Lightning Talk (10 minutes)
Romain Dorgueil
 
Learn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik CubeLearn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik Cube
Manoj Kumar
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
Dave Cross
 
Drupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the islandDrupal 8: A story of growing up and getting off the island
Drupal 8: A story of growing up and getting off the island
Angela Byron
 
"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo
Yandex
 
Defensive Coding Crash Course Tutorial
Defensive Coding Crash Course TutorialDefensive Coding Crash Course Tutorial
Defensive Coding Crash Course Tutorial
Mark Niebergall
 
Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)Diving into HHVM Extensions (php[tek] 2016)
Diving into HHVM Extensions (php[tek] 2016)
James Titcumb
 
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Thoughtworks
 
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP GeneratorsA Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
Mark Baker
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
vibrantuser
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
Kris Wallsmith
 
Intro to PHP for Beginners
Intro to PHP for BeginnersIntro to PHP for Beginners
Intro to PHP for Beginners
mtlgirlgeeks
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
Nikita Popov
 

Viewers also liked (8)

Cleancode
CleancodeCleancode
Cleancode
hendrikvb
 
Json In 5 Slices.Key
Json In 5 Slices.KeyJson In 5 Slices.Key
Json In 5 Slices.Key
hendrikvb
 
Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003
hendrikvb
 
China.z / Trojan.XorDDOS - Analysis of a hack
China.z / Trojan.XorDDOS - Analysis of a hackChina.z / Trojan.XorDDOS - Analysis of a hack
China.z / Trojan.XorDDOS - Analysis of a hack
hendrikvb
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
In a Rocket
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
Kirsty Hulse
 
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job? Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Succession “Losers”: What Happens to Executives Passed Over for the CEO Job?
Stanford GSB Corporate Governance Research Initiative
 
Json In 5 Slices.Key
Json In 5 Slices.KeyJson In 5 Slices.Key
Json In 5 Slices.Key
hendrikvb
 
Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003
hendrikvb
 
China.z / Trojan.XorDDOS - Analysis of a hack
China.z / Trojan.XorDDOS - Analysis of a hackChina.z / Trojan.XorDDOS - Analysis of a hack
China.z / Trojan.XorDDOS - Analysis of a hack
hendrikvb
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
hendrikvb
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
In a Rocket
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
Kirsty Hulse
 
Ad

Similar to Source Filters in Perl 2010 (20)

Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
Jesse Vincent
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
Michael Pirnat
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
Michael Koby
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
David Black
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
Kenneth Geisshirt
 
Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010
Michelangelo van Dam
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
Bhavin Javia
 
Designing code
Designing codeDesigning code
Designing code
Steve Smith
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
Message passing
Message passingMessage passing
Message passing
Damien Krotkine
 
Clean Manifests with Puppet::Tidy
Clean Manifests with Puppet::TidyClean Manifests with Puppet::Tidy
Clean Manifests with Puppet::Tidy
Puppet
 
Rails console
Rails consoleRails console
Rails console
Reuven Lerner
 
Mojolicious
MojoliciousMojolicious
Mojolicious
Marcus Ramberg
 
Dev traning 2016 basics of PHP
Dev traning 2016   basics of PHPDev traning 2016   basics of PHP
Dev traning 2016 basics of PHP
Sacheen Dhanjie
 
Designing Auto Generated Codes
Designing Auto Generated CodesDesigning Auto Generated Codes
Designing Auto Generated Codes
Hiroshi Kikuchi
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
Kenneth Geisshirt
 
CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5
neilbowers
 
Documenting with xcode
Documenting with xcodeDocumenting with xcode
Documenting with xcode
Goran Blazic
 
Intro to C++
Intro to C++Intro to C++
Intro to C++
Ahmed Farag
 
Hiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret SauceHiveminder - Everything but the Secret Sauce
Hiveminder - Everything but the Secret Sauce
Jesse Vincent
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
Michael Pirnat
 
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret SauceBeijing Perl Workshop 2008 Hiveminder Secret Sauce
Beijing Perl Workshop 2008 Hiveminder Secret Sauce
Jesse Vincent
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
Michael Koby
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
David Black
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
Kenneth Geisshirt
 
Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010
Michelangelo van Dam
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
Bhavin Javia
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
David Stockton
 
Clean Manifests with Puppet::Tidy
Clean Manifests with Puppet::TidyClean Manifests with Puppet::Tidy
Clean Manifests with Puppet::Tidy
Puppet
 
Dev traning 2016 basics of PHP
Dev traning 2016   basics of PHPDev traning 2016   basics of PHP
Dev traning 2016 basics of PHP
Sacheen Dhanjie
 
Designing Auto Generated Codes
Designing Auto Generated CodesDesigning Auto Generated Codes
Designing Auto Generated Codes
Hiroshi Kikuchi
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
Kenneth Geisshirt
 
CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5
neilbowers
 
Documenting with xcode
Documenting with xcodeDocumenting with xcode
Documenting with xcode
Goran Blazic
 
Ad

Recently uploaded (20)

AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Vaibhav Gupta BAML: AI work flows without Hallucinations
Vaibhav Gupta BAML: AI work flows without HallucinationsVaibhav Gupta BAML: AI work flows without Hallucinations
Vaibhav Gupta BAML: AI work flows without Hallucinations
john409870
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Rusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond SparkRusty Waters: Elevating Lakehouses Beyond Spark
Rusty Waters: Elevating Lakehouses Beyond Spark
carlyakerly1
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
Vaibhav Gupta BAML: AI work flows without Hallucinations
Vaibhav Gupta BAML: AI work flows without HallucinationsVaibhav Gupta BAML: AI work flows without Hallucinations
Vaibhav Gupta BAML: AI work flows without Hallucinations
john409870
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptxIncreasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Increasing Retail Store Efficiency How can Planograms Save Time and Money.pptx
Anoop Ashok
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
Electronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploitElectronic_Mail_Attacks-1-35.pdf by xploit
Electronic_Mail_Attacks-1-35.pdf by xploit
niftliyevhuseyn
 
Linux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdfLinux Professional Institute LPIC-1 Exam.pdf
Linux Professional Institute LPIC-1 Exam.pdf
RHCSA Guru
 
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
IEDM 2024 Tutorial2_Advances in CMOS Technologies and Future Directions for C...
organizerofv
 
Big Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur MorganBig Data Analytics Quick Research Guide by Arthur Morgan
Big Data Analytics Quick Research Guide by Arthur Morgan
Arthur Morgan
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Heap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and DeletionHeap, Types of Heap, Insertion and Deletion
Heap, Types of Heap, Insertion and Deletion
Jaydeep Kale
 
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc Webinar: Consumer Expectations vs Corporate Realities on Data Broker...
TrustArc
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Technology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data AnalyticsTechnology Trends in 2025: AI and Big Data Analytics
Technology Trends in 2025: AI and Big Data Analytics
InData Labs
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 

Source Filters in Perl 2010

  • 1. Source Filters in perl Belgian perl workshop 2010 hendrik van belleghem
  • 2. Source Filters in perl Belgian perl workshop 2010 hendrik van belleghem Spoiler warning: This talk might ruin the magic behind Acme::bleach and acme::buffy
  • 3. Eh?
  • 4. Eh? • What are Source Filters?
  • 5. Eh? • What are Source Filters? • Writing Source Filters
  • 6. Eh? • What are Source Filters? • Writing Source Filters • Magic revealed!
  • 7. What are source filters?
  • 8. What are source filters? • Manipulate code during compile time
  • 9. What are source filters? • Manipulate code during compile time • Modules loaded during compile time
  • 10. What are source filters? • Manipulate code during compile time • Modules loaded during compile time • Only works on main::
  • 11. What are source filters? • Manipulate code during compile time • Modules loaded during compile time • Only works on main:: • Only parses $0
  • 13. Example Acme::bleach before after For *really* clean programs
  • 14. Example Acme::bleach Before
  • 15. Example Acme::bleach Before #!/usr/bin/perl use Acme::Bleach; print “Hello World”;
  • 16. Example Acme::bleach After
  • 17. Example Acme::bleach After #!/usr/bin/perl use Acme::Bleach;
  • 18. Example Acme::bleach After #!/usr/bin/perl use Acme::Bleach;
  • 19. Example Acme::bleach • Live demo?
  • 22. Writing source filters • Approaches: • Filter::Util::Call
  • 23. Writing source filters • Approaches: • Filter::Util::Call • Filter::Simple
  • 24. Writing source filters • Approaches: • Filter::Util::Call • Filter::Simple • From scratch
  • 25. Writing source filters • Approaches: • Filter::Util::Call • Filter::Simple • From scratch • Our example: Line numbers
  • 27. Writing source filters • Problem: Filter the code first
  • 28. Writing source filters • Problem: Filter the code first • Adding line numbers
  • 29. Writing source filters • Problem: Filter the code first • Adding line numbers • Bleaching (Acme::Bleach)
  • 30. Writing source filters • Problem: Filter the code first • Adding line numbers • Bleaching (Acme::Bleach) • Buffy’ing (Acme::Buffy)
  • 31. Writing source filters • Problem: Filter the code first • Adding line numbers • Bleaching (Acme::Bleach) • Buffy’ing (Acme::Buffy) • Encrypting (Filter::CBC)
  • 32. Writing source filters • Problem: Filter the code first • Adding line numbers • Bleaching (Acme::Bleach) • Buffy’ing (Acme::Buffy) • Encrypting (Filter::CBC) • Problem: Don’t filter filtered code again
  • 35. Filter::Util::Call • Module by Paul Marquess • Part of Perl core
  • 36. Filter::Util::Call • Module by Paul Marquess • Part of Perl core • Could be easier
  • 37. Filter::Util::Call package MyFilter; use Filter::Util::Call; sub import { my ($type, @arguments) = @_ ; filter_add([ ]) ; } sub filter { my ($self) = @_ ; my ($status) ; $status = filter_read(); #Do magic with $_ if $status > 0 return $status; } 1;
  • 38. Filter::Util::Call package MyFilter; use Filter::Util::Call; import is called when module is “used” sub import { my ($type, @arguments) = @_ ; filter_add([ ]) ; } sub filter { my ($self) = @_ ; my ($status) ; $status = filter_read(); #Do magic with $_ if $status > 0 return $status; } 1;
  • 39. Filter::Util::Call package MyFilter; use Filter::Util::Call; sub import { my ($type, @arguments) = @_ ; filter_add([ ]) ; } sub filter { my ($self) = @_ ; my ($status) ; $status = filter_read(); if ($status) { $_ =~ s/World/Belgian Perl Workshop/g; } return $status; } 1; # Hello World -> Hello Belgian Perl Workshop
  • 40. Filter::NumberLines package Filter::NumberLines; use Filter::Util::Call; sub import { my ($type, @arguments) = @_ ; filter_add([ ]) ; } sub filter { my ($self) = @_ ; my ($status) ; $status = filter_read(); if ($status) { $_ =~ s/^d+:t//gm; } return $status; } 1;
  • 43. Filter::NumberLines • One Problem.. • We have to add the line numbers manually
  • 44. Filter::NumberLines • One Problem.. • We have to add the line numbers manually • Introducing auto-filtering code...
  • 46. Filter::NumberLines open(INFILE,"<$0") || die $!; open(OUTFILE,">$0.bak") || die $!; my $line = 0; my $no_go = 0; my $past_use = 0; $|++; while(<INFILE>) { $line++; if ($past_use && /^d+:t/) { $no_go++; last; } if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; } if (/use Filter::NumberLines;/) { $past_use++; } print OUTFILE $_; } close(OUTFILE); close (INFILE); if (!$no_go) { unlink($0) || die $!; rename ("$0.bak",$0); exit; } else { unlink("$0.bak") || die $!; }
  • 50. Filter::Simple • Module by Damian Conway • Part of Perl core
  • 51. Filter::Simple • Module by Damian Conway • Part of Perl core • Much easier than Filter::Util::Call
  • 52. Filter::Simple package MyFilter; use Filter::Simple; FILTER { do_some_magic(); }; 1;
  • 56. Filter::NumberLines • One Problem.. • We have to add the line numbers again
  • 57. Filter::NumberLines • One Problem.. • We have to add the line numbers again • Introducing auto-filtering code...
  • 59. Filter::NumberLines open(INFILE,"<$0") || die $!; open(OUTFILE,">$0.bak") || die $!; my $line = 0; my $no_go = 0; my $past_use = 0; $|++; while(<INFILE>) { $line++; if ($past_use && /^d+:t/) { $no_go++; last; } if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; } if (/use Filter::NumberLines::Simple;/) { $past_use++; } print OUTFILE $_; } close(OUTFILE); close (INFILE); if (!$no_go) { unlink($0) || die $!; rename ("$0.bak",$0); exit; } else { unlink("$0.bak") || die $!; }
  • 61. From Scratch package Filter::NumberLines::Scratch; sub scratch { local $_ = pop; s/^d+:t//gm; return $_; } sub import { open 0 or print "Can't number '$0'n" and exit; my $line = 0; my $no_go = 0; my $past_use = 0; my $file; while(<0>) { $line++; if ($past_use && /^d+:t/) { $no_go++; $file = join "",$_,<0>; last; } if ($past_use) { $_ =sprintf("%03d",$line).":t".$_; } if (/use Filter::NumberLines::Scratch;/) { { $past_use++; } $file .= $_; } if ($no_go) { do { eval scratch $file; exit; } } else { open 0, ">$0" or print "Cannot number '$0'n" and exit; print {0} $file and exit; } } 1;
  • 64. From Scratch Easy Bree zy!
  • 65. From Scratch Easy Bree zy! • Filter code..
  • 66. From Scratch Easy Bree zy! • Filter code.. • and eval’uate it.
  • 70. Acme::Bleach • Bleaches code • Step 1: Convert code to bit stream
  • 71. Acme::Bleach • Bleaches code • Step 1: Convert code to bit stream • Step 2: Convert bits into tabs (1) and spaces (0)
  • 72. Acme::Bleach • Bleaches code • Step 1: Convert code to bit stream • Step 2: Convert bits into tabs (1) and spaces (0) • Reverse to unbleach
  • 73. Acme::Bleach • Bleaches code • Step 1: Convert code to bit stream • Step 2: Convert bits into tabs (1) and spaces (0) • Reverse to unbleach • Written by Damian Conway
  • 74. Acme::Bleach • Bleaches code • Step 1: Convert code to bit stream • Step 2: Convert bits into tabs (1) and spaces (0) • Reverse to unbleach • Written by Damian Conway • from scratch
  • 76. Acme::Bleach package Acme::Bleach; my $tie = " t"x8; sub whiten { local $_ = unpack "b*", pop; tr/01/ t/; s/(.{9})/$1n/g; $tie.$_ } sub brighten { local $_ = pop; s/^$tie|[^ t]//g; tr/ t/01/; pack "b*", $_ } sub dirty { $_[0] =~ /S/ } sub dress { $_[0] =~ /^$tie/ } open 0 or print "Can't rebleach '$0'n" and exit; (my $shirt = join "", <0>) =~ s/.*^s*uses+Acme::Bleachs*;n//sm; local $SIG{__WARN__} = &dirty; do { eval brighten $shirt; exit } unless dirty $shirt && not dress $shirt; open 0, ">$0" or print "Cannot bleach '$0'n" and exit; print {0} "use Acme::Bleach;n", whiten $shirt and exit;
  • 80. Acme::Buffy • Buffies code • Step 1: Convert code to bit stream
  • 81. Acme::Buffy • Buffies code • Step 1: Convert code to bit stream • Step 2: Convert bits into uppercase and lowercase letters from the word Buffy
  • 82. Acme::Buffy • Buffies code • Step 1: Convert code to bit stream • Step 2: Convert bits into uppercase and lowercase letters from the word Buffy • Written by Leon Brocard
  • 83. Acme::Buffy • Buffies code • Step 1: Convert code to bit stream • Step 2: Convert bits into uppercase and lowercase letters from the word Buffy • Written by Leon Brocard • Written from scratch
  • 85. Acme::Buffy my $horns = “BUffY bUFFY” x 2; my $i = 0; sub _slay { my $willow = unpack "b*", pop; my @buffy = ( 'b', 'u', 'f', 'f', 'y', ' ' ); my @BUFFY = ( 'B', 'U', 'F', 'F', 'Y', "t" ); my $demons = $horns; foreach ( split //, $willow ) { $demons .= $_ ? $BUFFY[$i] : $buffy[$i]; $i++; $i = 0 if $i > 5; } return $demons; } sub _unslay { my $demons = pop; $demons =~ s/^$horns//g; my @willow; foreach ( split //, $demons ) { push @willow, /[buffy ]/ ? 0 : 1; } return pack "b*", join '', @willow; }
  • 87. Acme::Buffy sub _evil { return $_[0] =~ /S/; } sub _punch { return $_[0] =~ /^$horns/; } sub import { open 0 or print "Can't rebuffy '$0'n" and exit; ( my $demon = join "", <0> ) =~ s/.*^s*uses+Acme::Buffys*;n//sm; local $SIG{__WARN__} = &evil; do { eval _unslay $demon; exit } unless _evil $demon and not _punch $demon; open my $fh, ">$0" or print "Cannot buffy '$0'n" and exit; print $fh "use Acme::Buffy;n", _slay $demon and exit; print "use Acme::Buffy;n", _slay $demon and exit; return; } "Grrr, arrrgh";
  • 90. Filter::CBC • Encrypts code using Crypt::CBC
  • 91. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher
  • 92. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher • Hardcoded or external algorithm & key phrase
  • 93. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher • Hardcoded or external algorithm & key phrase • Pass parameters in use statement
  • 94. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher • Hardcoded or external algorithm & key phrase • Pass parameters in use statement • Based on Filter::Util::Call
  • 95. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher • Hardcoded or external algorithm & key phrase • Pass parameters in use statement • Based on Filter::Util::Call • Written by uhm me
  • 96. Filter::CBC • Encrypts code using Crypt::CBC • Can use any algorithm that uses CBC cipher • Hardcoded or external algorithm & key phrase • Pass parameters in use statement • Based on Filter::Util::Call • Written by uhm me use Filter::CBC "Rijndael","my secret key";
  • 98. Filter::CBC my $blank = “This space is left blank intentionally”; sub import { my ($type) = shift @_; my $algorithm = shift || "Rijndael"; $algorithm = $Ciphers{uc $algorithm} || $algorithm; my $key = shift || $blank; my ($ref) = [ ]; $cipher = Crypt::CBC->new(-key => $key,-cipher => $algorithm); if (defined $algorithm && defined $key) { open(F,"<$0") || die $!; flock(F,2); seek(F,0,0); my @CODE = (); my $past_use; while(<F>) { if (/^# $blank/ && !$past_use) { close(F); last; } if (/use Filter::CBC/) { push(@CODE,$_); $past_use++; next; } if (!$past_use) { push(@CODE,$_); } else
  • 100. Filter::CBC { my $code = $_; local $/ = undef; $code .= <F>; splice(@CODE,-2,0,"# $blank"); $code = $cipher->encrypt($code); open(OUTFILE,">$0.bak") || die $!; binmode(OUTFILE); print OUTFILE @CODE,$code; close(OUTFILE); close(F); unlink("$0") || die $!; rename ("$0.bak",$0) || die $!; exit; } } } filter_add(bless $ref) ; } sub filter { my ($self) = @_ ; my ($status); local $/ = undef; if (($status = filter_read()) > 0) { $_ = $cipher->decrypt($_); } return $status ; } 1;
  • 101. Questions? • Time for bonus slides?
  • 102. Switch
  • 103. Switch use Switch; switch ($val) { case 1 { print "number 1"; } case "a" { print "string a"; } case [1..10,42] { print "number in list"; } case /w+/ { print "pattern"; } else { print "previous case not true"; } }
  • 104. Switch use Switch; switch ($val) { case 1 { print "number 1"; } case "a" { print "string a"; } case [1..10,42] { print "number in list"; } case /w+/ { print "pattern"; } else { print "previous case not true"; } } is turned into
  • 105. Switch use Switch; switch ($val) { case 1 { print "number 1"; } case "a" { print "string a"; } case [1..10,42] { print "number in list"; } case /w+/ { print "pattern"; } else { print "previous case not true"; } } is turned into if ($var == 1) { print “number 1”; } elsif ($var eq “a”) { print “string a”; } elsif (grep /$var [1..10,42]) { print "number in list" } elsif ($var=~ /w+/) { print “pattern”; } else { print “previous case not true”; }