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

More Related Content

What's hot

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
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
Movel
 
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
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
 

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
 
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)
 
Learn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik CubeLearn JavaScript by modeling Rubik Cube
Learn JavaScript by modeling Rubik Cube
 
Advanced Perl Techniques
Advanced Perl TechniquesAdvanced Perl Techniques
Advanced Perl Techniques
 
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
 
"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo"Managing API Complexity". Matthew Flaming, Temboo
"Managing API Complexity". Matthew Flaming, Temboo
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Defensive Coding Crash Course Tutorial
Defensive Coding Crash Course TutorialDefensive Coding Crash Course Tutorial
Defensive Coding Crash Course Tutorial
 
Xtext Webinar
Xtext WebinarXtext Webinar
Xtext Webinar
 
Starting Out With PHP
Starting Out With PHPStarting Out With PHP
Starting Out With PHP
 
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)
 
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...
 
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
 
Php training100%placement-in-mumbai
Php training100%placement-in-mumbaiPhp training100%placement-in-mumbai
Php training100%placement-in-mumbai
 
Advanced symfony Techniques
Advanced symfony TechniquesAdvanced symfony Techniques
Advanced symfony Techniques
 
Intro to PHP for Beginners
Intro to PHP for BeginnersIntro to PHP for Beginners
Intro to PHP for Beginners
 
Intro to Perl and Bioperl
Intro to Perl and BioperlIntro to Perl and Bioperl
Intro to Perl and Bioperl
 
Scala in Practice
Scala in PracticeScala in Practice
Scala in Practice
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
PHP 7 – What changed internally?
PHP 7 – What changed internally?PHP 7 – What changed internally?
PHP 7 – What changed internally?
 

Viewers also liked

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
 

Viewers also liked (8)

Cleancode
CleancodeCleancode
Cleancode
 
Json In 5 Slices.Key
Json In 5 Slices.KeyJson In 5 Slices.Key
Json In 5 Slices.Key
 
Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003Scrabbling Code - Beatnik - YAPC::Eu::2003
Scrabbling Code - Beatnik - YAPC::Eu::2003
 
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
 
Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101Web Apps in Perl - HTTP 101
Web Apps in Perl - HTTP 101
 
Learn BEM: CSS Naming Convention
Learn BEM: CSS Naming ConventionLearn BEM: CSS Naming Convention
Learn BEM: CSS Naming Convention
 
SEO: Getting Personal
SEO: Getting PersonalSEO: Getting Personal
SEO: Getting Personal
 
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?
 

Similar to Source Filters in Perl 2010

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
 

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
 
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
 
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
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 
Ruby 2: some new things
Ruby 2: some new thingsRuby 2: some new things
Ruby 2: some new things
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010Php Crash Course - Macq Electronique 2010
Php Crash Course - Macq Electronique 2010
 
Write your Ruby in Style
Write your Ruby in StyleWrite your Ruby in Style
Write your Ruby in Style
 
Designing code
Designing codeDesigning code
Designing code
 
Intermediate OOP in PHP
Intermediate OOP in PHPIntermediate OOP in PHP
Intermediate OOP in PHP
 
Message passing
Message passingMessage passing
Message passing
 
Clean Manifests with Puppet::Tidy
Clean Manifests with Puppet::TidyClean Manifests with Puppet::Tidy
Clean Manifests with Puppet::Tidy
 
Rails console
Rails consoleRails console
Rails console
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Dev traning 2016 basics of PHP
Dev traning 2016   basics of PHPDev traning 2016   basics of PHP
Dev traning 2016 basics of PHP
 
Designing Auto Generated Codes
Designing Auto Generated CodesDesigning Auto Generated Codes
Designing Auto Generated Codes
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5CPAN Exporter modules for Perl 5
CPAN Exporter modules for Perl 5
 
Documenting with xcode
Documenting with xcodeDocumenting with xcode
Documenting with xcode
 
Intro to C++
Intro to C++Intro to C++
Intro to C++
 

Recently uploaded

Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
saastr
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
kumardaparthi1024
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
Wouter Lemaire
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
ssuserfac0301
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
Pravash Chandra Das
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
tolgahangng
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
Zilliz
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
Pixlogix Infotech
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
Zilliz
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
Postman
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 

Recently uploaded (20)

Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStrDeep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
Deep Dive: Getting Funded with Jason Jason Lemkin Founder & CEO @ SaaStr
 
GenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizationsGenAI Pilot Implementation in the organizations
GenAI Pilot Implementation in the organizations
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
UI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentationUI5 Controls simplified - UI5con2024 presentation
UI5 Controls simplified - UI5con2024 presentation
 
Taking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdfTaking AI to the Next Level in Manufacturing.pdf
Taking AI to the Next Level in Manufacturing.pdf
 
HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
Serial Arm Control in Real Time Presentation
Serial Arm Control in Real Time PresentationSerial Arm Control in Real Time Presentation
Serial Arm Control in Real Time Presentation
 
Fueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte WebinarFueling AI with Great Data with Airbyte Webinar
Fueling AI with Great Data with Airbyte Webinar
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Best 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERPBest 20 SEO Techniques To Improve Website Visibility In SERP
Best 20 SEO Techniques To Improve Website Visibility In SERP
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 
Building Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and MilvusBuilding Production Ready Search Pipelines with Spark and Milvus
Building Production Ready Search Pipelines with Spark and Milvus
 
WeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation TechniquesWeTestAthens: Postman's AI & Automation Techniques
WeTestAthens: Postman's AI & Automation Techniques
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 

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”; }

Editor's Notes