SlideShare a Scribd company logo
Good Evils in Perl
 Kang-min Liu <gugod@gugod.org>
$speaker.meta
•                              •   http://handlino.com/
    Kang-min Liu
    gugod

•   http://gugod.org

•   http://twitter.com/gugod

•   gugod@gugod.org
perl is...
get things done
glue languagee
TIMTOWTDI
There is more then one way to do it
the good perl
pragma
pragma = one small
               english word.

               Module = title-cased

               just an convention.




Module::Acme
  pragma
warnings
gives you good warning messages
Can anyone tell me if
        there’s any problem in
        this small program ?

        foo.pl




#!/usr/bin/perl
print $foo;
print quot;Helloquot;;
strict
Can any one see a
                  problem in this program ?




#!/usr/bin/perl
use warnings;

print $name;
print quot;Helloquot;;
it runs!
(it should break)
$name is undefined
use strict;
it breaks your program
in a nice way :-D
feature
Perl 5.10
← Perl6
use feature;
use feature ‘:5.10’
given - when - default
given ($foo) {
    when (1)            { say quot;$foo == 1quot; }
    when ([2,3])        {
        say quot;$foo ==   2 || $foo == 3quot;
    }
    when (/^a[bc]d$/)   {
        say quot;$foo eq   'abd' || $foo eq 'acd'quot;
    }
    when ($_ > 100)     { say quot;$foo > 100quot; }
    default             { say quot;None of the abovequot; }
}
state variables

 sub counter {
    state $counts = 0;
    $counts += 1;
 }
say

say quot;hiquot;;
print quot;hinquot;;
say quot;hiquot;;
use 5.010;
Perl6::*
Perl6 functions implemented in Perl5
Perl6::Junctions
      any, all
Q: How to test if an
array contains a specific
value ?
Does @ar
contains 42 ?
$found = 0;
foreach $a (@ar) {
    if ($a == 42) {
        $found = 1;
        last;
    }
}
if ($fount) {
   ...
}
if ( grep { $_ == 42 } @ar ) {
   ...
}
if ( grep /^42$/ @ar ) {
   ...
}
use Perl6::Junction qw/ all any none one /;
if ( any(@ar) == 42 ) {
    ...
}
if (all(@ar) > 42) {
   ...
}
if (none(@ar) > 42) {
   ...
}
if (one(@ar) > 42) {
   ...
}
any(values %params) == undef


    html form validation
any(@birthday) < str2time(quot;1980/01/01quot;)
Can anyone see what it
                      does now ?

                      Can anyone write a
                      nested loop version in 10
                      seconds ?




if ( any(@a) == any(@b) ) {
   ...
}
• Perl6::Junction (any, all)
• Perl6::Perl
• Perl6::Builtins (system, caller)
• Perl6::Form
• Perl6::Gather
autobox
my $range = 10−>to(1);
# => [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
quot;Hello, world!quot;−>uc();
# => quot;HELLO, WORLD!quot;
TryCatch
first class try catch semantics
sub foo {
  eval {
    # some code that might die
    return quot;return value from fooquot;;
  }
  if ($@) {
    ...
  }
}
sub foo {
  try {
    # some code that might die
    return quot;return value from fooquot;;
  }
  catch (Some::Error $e where { $_->code > 100 } ) {
    ...
  }
}
Sub::Alias
easier function alias
sub name { quot;gugodquot; }

alias get_name => 'name';
alias getName => 'name';
self
my $self = shift;
package MyClass;

sub myMethod {
    my $self = shift;
    ...
}
package MyClass;
use self;
sub myMethod {
    ...
}
Moose
Yet-another
OO sub-system
EH?
¿ More ?
OF COURSE
Perl (5) is not like other Object Oriented Languages... does
NOT have an OO built-in


That's why you should learn perl if you want to learn OO!

You can learn how to make an object system, not just how
to use it.




                                  Dan Kogai
package Point;
use Moose;

has 'x' => (is => 'rw', isa => 'Int');
has 'y' => (is => 'rw', isa => 'Int');

sub clear {
    my $self = shift;
    $self->x(0);
    $self->y(0);
}
MooseX::Declare
class BankAccunt {
    has 'balance' => (
        isa => 'Num', is => 'rw', default => 0
    );

    method deposit (Num $amount) {
        $self->balance( $self−>balance + $amount );
    }

    method withdraw (Num $amount) {
        my $current_balance = $self−>balance();
        ( $current_balance >= $amount )
            || confess quot;Account overdrawnquot;;
        $self->balance( $current_balance − $amount );
    }
}
Rubyish
package Cat;
use Rubyish;

attr_accessor quot;namequot;, quot;colorquot;;

def sound { quot;meow, meowquot; }

def speak {
    print quot;A cat goes quot; . $self−>sound . quot;nquot;;
}
the evil perl
prototype
sub doMyWork {
    my ($arr1, $arr2) = @_;
    my @arr1 = @$arr1;
    my @arr2 = @$arr2;
    ...
}

doMyWork(@foo, @bar);
sub doMyWork(@@) {
    my ($arr1, $arr2) = @_;
    my @arr1 = @$arr1;
    my @arr2 = @$arr2;
    ...
}

doMyWork(@foo, @bar);
if (many { $_ > 50 } @arr) {
    ....
}
sub many(&@) {
    my ($test_sub, @arr) = @_;
    ...
}
AUTOLOAD
Good Evils In Perl
sub AUTOLOAD {
    my $program = $AUTOLOAD;
    $program =~ s/.*:://;
    system($program, @_);
}
date();
who('am', 'i');
ls('−l');
Source Filter
package BANG;
use Filter::Simple;

FILTER {
   s/BANGs+BANG!!!/die 'BANG' if $BANG/g;
};

1;
use Acme::Morse;
.--.-..--..---.-.--..--.-..--..---.-.--.
.-.-........---..-..---.-..-.--..---.--.
..-.---......-...-...-..--..-.-.-.--.-..
----..-.-.--.-..--..-.-...---.-..---.--.
.-...-..--.---...-.-....
Module::Compile
DB
inheritable built-in debugger
# from self.pm
sub _args {
    my $level = 2;
    my @c = ();
    package DB;
    @c = caller($level++)
        while !defined($c[3]) || $c[3] eq '(eval)';
    return @DB::args;
}
PadWalker
runtime stack traveler
sub inc_x {
  my $h = peek_my(1);
  ${ $h->{'$x'} }++;
}
Binding
easier padwalker
use Binding;
sub inc_x {
    my $b = Binding->of_caller;
    $b->eval('$x + 1');
}

sub two {
    my $x = 1;
    inc_x;
}
Devel::Declare
  compile-time magician
Compile time
code injection
How it works
• you define “declarator” keywords
• it let compiler stop at the keywords
• your code parse the current line in your
  way, maybe re-write it
• you re-place current line with the new
  version
• it resumes the compiler on the current line
def foo($arg1, $arg2) {
    ....
}
def foo($arg1, $arg2) {
    ....
}
def foo($arg1, $arg2) {
      ....
  }



sub foo {
    my ($arg1, $arg2) = @_;
}
B::Hooks::*
more compile time fun
the better perl
Good Evils In Perl
to extend perl
the perfect perl
the perfect language?
Perl6 is perfect
The most extendable
programming language
• variables
• functions, methods
• operator overloading
• operators
• grammars / rules
• sub-language
Perl6 is many languages
Perl6 are many languages
Perl5 world

• B::Generate
• Source Filter
• Devel::Declare
Conclusion
Perl is like the Force. It
has a light side, a dark
side, and it holds the
universe together.

             Larry Wall
Good Evils In Perl
The End
Thanks for listening

More Related Content

Good Evils In Perl