Modern Perl
-
Upload
marcos-rebelo -
Category
Technology
-
view
5.847 -
download
1
Transcript of Modern Perl
Modern Perl
use v5.10;
say
The usual:print "Hello, World!\n";
print my_sub_call(...), "\n";
or:say 'Hello, World!';
say my_sub_call(...);
Defined or
The usual:
$name = 'oleber'
if not defined $name;
or
$name //= 'oleber';
switch
if ($value =~ /pippo/) {
...
}
elsif ($va1ue eq 'alpha') {
...
}
elsif ($value == 1 or $value == 2 ) {
...
}
else {
...
}
switch
given ($value) {
when (/pippo/) {
...
}
when ('alpha') {
...
}
when ([1,2]) {
...
}
default {
...
}
}
Smart matching
The usual:
if ( grep {/pippo/} @array ) {
}
or
if ( @array ~~ /pippo/ ) {
}
state
the usual
{
my $static_var = 0;
sub xpto { ... }
}
or
sub xpto {
state $static_var = 0;
...
}
New RegExp
Named Capture Buffers
'Michael Jackson' =~
/(?.*)\s(?.*)/;
%+ is ('fn'=>'Michael', 'ln'=>'Jackson'}
"\K" escape, floating length positive lookbehind:
s/(foo)bar/$1/g
becomes
s/foo\Kbar//g
Backtracking control verbs
...
Object Oriented
use Moose;
package Person;
use Moose;# now it's a Moose class!# imports strict and warnings
...
no Moose;__PACKAGE__->meta->make_immutable;
Moose attributes
has id => ( is => 'ro', isa => 'Int',);
has name => ( is => 'rw', isa => 'Str',);
my $person = new Person(id => 123, name => 'John');
$person->name('peter'); # OK$person->id(12); # NOK
Moose Types
Many types are already defined like:Num, Int, Str, ClassName, Ref, ScalarRef, ...
Even some parameterizedArrayRef[Int] # an array of integers
HashRef[CodeRef] # a hash of str to Code ref
...
Define your types
use Moose::Util::TypeConstraints;
subtype 'Telephone' => as 'Str' => where { $_ =~ /^\d+$/};
no Moose::Util::TypeConstraints;
has telephone => ( is => 'rw', isa => 'Telephone',);
$person->telephone('35196219374'); # OK$person->telephone('XPTO'); # NOK
Moose class Inheritance
package User;use Moose;
extends 'Person';
has login => ( is => 'rw', isa => 'Str',);
...
my $user = new User(id => 52, login => 'oleber')
Moose Method
sub do_login { my ($self, $password) = @_; ...}
Moose method modifiers
before do_login => sub { my ( $self, $pass ) = @_; warn "Called login() with $pass\n";};
around name => sub { my ($orig, $self, @args) = @_; return ucfirst lc $self->$orig(@args);};
...
Moose Constructor
The new() method is created for you, and it simply does the right thing. You should never need to define your own new() constructor!!!
You can provide a BUILD() method in your class. Moose will call this for you after creating a new object.
MooseDestructor
If you really need it in Perl ...
The old DESTROY is used internally by Moose
You shall use the DEMOLISH() method
Call methods on native types
autobox
use JSON;say to_json [ map { $_ ** 2 } @array ];
use autobox;
local *ARRAY::map = sub { my ( $self, $block ) = @_; return [map {&$block($_)} @$self ];};
local *ARRAY::to_json = sub { return to_json(shift);};
say @array->map( sub { $_ ** 2 } )->to_json;
autobox
It allows methods to be called on integers, floats, strings,
arrays, hashes, and code references in exactly the same manner as
blessed references."hello world!"->upper()
is equivalent to
SCALAR::upper("hello world!")
[1..10]->foreach(sub { ... })
resolves to:
ARRAY::foreach([1..10], sub { ... })
autobox
The autobox module gives the illusion that Perl's types are first-class objects.
Cpan has already some Packages with the most logical functions implementation. See:autobox::Core
Moose::Autobox
Exception handling
Error
use Error qw(:try);
try { throw ...;} catch Error::IO with { my $E = shift; warn "File $E->{'-file'} had a problem\n";} except { my $E = shift; warn "ERROR: " . Dumper $E;} otherwise { say "ALL OK\n";} finally { say "Finished"}; # Don't forget the trailing ;
TryCatch
use TryCatch;
try { die ...} catch ( PKG_1 $e where { $_->code > 100 } ) { ...} catch ( PKG_2 $e ) { ...} catch ( $e ) { ...} catch { ...}
It is better to die() than to return() in failure. (Paul Fenwick)
The Box Jellyfish
Saltwater Crocodile
Blue Ring Octopus
Stone fish
Red Back Spider
Funnel Web Spider
autodie
open(my $FH, ">>", $path) or die "Can't open $!";
system($cmd) == 0 or die "system failed: $?";
if ( defined ( my $pid = fork() ) ) { if ( $pid != 0 ) { # parent } else { # child }} else { die "Can't fork";}
autodie
use autodie qw(:all);
open(my $FH, ">>", $path) or die "Can't open $!";
system($cmd) == 0 or die "system failed: $?";
if ( defined ( my $pid = fork() ) ) { if ( $pid != 0 ) { # parent } else { # child }} else { die "Can't fork";}
autodie
use autodie qw(:all);
open(my $FH, ">>", $path);
system($cmd) == 0 or die "system failed: $?";
if ( defined ( my $pid = fork() ) ) { if ( $pid != 0 ) { # parent } else { # child }} else { die "Can't fork";}
autodie
use autodie qw(:all);
open(my $FH, ">>", $path);
system($cmd);
if ( defined ( my $pid = fork() ) ) { if ( $pid != 0 ) { # parent } else { # child }} else { die "Can't fork";}
autodie
use autodie qw(:all);
open(my $FH, ">>", $path);
system($cmd);
if ( ( my $pid = fork() ) != 0 ) { # parent} else { # child}
autodie error analyse
eval { use autodie; open(my $FH, '