Good Evils In Perl
-
Upload
kang-min-liu -
Category
Technology
-
view
4.038 -
download
6
Transcript of Good Evils In Perl
Good Evils in PerlKang-min Liu <[email protected]>
$speaker.meta• 劉康民
Kang-min Liugugod
• http://gugod.org
• http://twitter.com/gugod
• http://handlino.com/和多股份有限公司
perl is...
get things done
glue languagee
TIMTOWTDIThere is more then one way to do it
the good perl
pragma
Module::Acmepragma
pragma = one small english word.
Module = title-cased
just an convention.
warningsgives you good warning messages
#!/usr/bin/perlprint $foo;print "Hello";
Can anyone tell me if there’s any problem in this small program ?
foo.pl
strict
#!/usr/bin/perluse warnings;
print $name;print "Hello";
Can any one see a problem in this program ?
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 - defaultgiven ($foo) { when (1) { say "\$foo == 1" } when ([2,3]) { say "\$foo == 2 || \$foo == 3" } when (/^a[bc]d$/) { say "\$foo eq 'abd' || \$foo eq 'acd'" } when ($_ > 100) { say "\$foo > 100" } default { say "None of the above" }}
state variables
sub counter { state $counts = 0; $counts += 1;}
say
say "hi";
print "hi\n";
say "hi";
use 5.010;
Perl6::*Perl6 functions implemented in Perl5
Perl6::Junctionsany, all
Q: How to test if an array contains a specific value ?
Does @arcontains 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("1980/01/01")
if ( any(@a) == any(@b) ) { ...}
Can anyone see what it does now ?
Can anyone write a nested loop version in 10 seconds ?
• 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 ]
"Hello, world!"−>uc();# => "HELLO, WORLD!"
TryCatch first class try catch semantics
sub foo { eval { # some code that might die return "return value from foo"; } if ($@) { ... }}
sub foo { try { # some code that might die return "return value from foo"; } catch (Some::Error $e where { $_->code > 100 } ) { ... }}
Sub::Aliaseasier function alias
sub name { "gugod" }
alias get_name => 'name';alias getName => 'name';
selfmy $self = shift;
package MyClass;
sub myMethod { my $self = shift; ...}
package MyClass;use self;sub myMethod { ...}
Moose後現代的物件導向系統
Yet-anotherOO 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 "Account overdrawn"; $self->balance( $current_balance − $amount ); }}
Rubyish
package Cat;use Rubyish;
attr_accessor "name", "color";
def sound { "meow, meow" }
def speak { print "A cat goes " . $self−>sound . "\n";}
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
sub AUTOLOAD { my $program = $AUTOLOAD; $program =~ s/.*:://; system($program, @_);}date();who('am', 'i');ls('−l');
Source Filter
package BANG;use Filter::Simple; FILTER { s/BANG\s+BANG!!!/die 'BANG' if \$BANG/g;};
1;
use Acme::Morse;.--.-..--..---.-.--..--.-..--..---.-.--..-.-........---..-..---.-..-.--..---.--...-.---......-...-...-..--..-.-.-.--.-..----..-.-.--.-..--..-.-...---.-..---.--..-...-..--.---...-.-....
Module::Compile
DBinheritable built-in debugger
# from self.pmsub _args { my $level = 2; my @c = (); package DB; @c = caller($level++) while !defined($c[3]) || $c[3] eq '(eval)'; return @DB::args;}
PadWalkerruntime stack traveler
sub inc_x { my $h = peek_my(1); ${ $h->{'$x'} }++;}
Bindingeasier padwalker
use Binding;sub inc_x { my $b = Binding->of_caller; $b->eval('$x + 1');}
sub two { my $x = 1; inc_x;}
Devel::Declarecompile-time magician
Compile timecode injection
• 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
How it works
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
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
The EndThanks for listening