Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

🐪 Perl — Guide PRO (Modern Perl / CPAN / Web / DBI / Tests)

Du script UNIX aux APIs web modernes : CPAN, DBI/DBIx, Mojolicious/Dancer2, Regex avancées, profiling NYTProf, sécurité (taint), packaging & CI.

1

Toolchain & Install

perlbrew/plenv, cpanm, Carton

Install
2

Syntaxe & Bases

scalaires, arrays, hashes, refs

Basics
3

Regex avancées

PCRE, lookaround, atomic, named

Regex
4

One-liners

-ne/-pe, -0777, autosplit

One
5

Modules & CPAN

cpanm, Carton, META.json

CPAN
6

OOP (Moose/Moo)

attrs, roles, immutabilité

OOP
7

DBI & DBIx::Class

connect, placeholders, schema

DBI
8

Fichiers & IO

encodage, layers, File::Temp

IO
9

Process/IPC

system, open3, IPC::Run

IPC
10

Mojolicious

routing, templates, websockets

Mojo
11

Dancer2

config, routes, plugins

Dancer2
12

PSGI/Plack

middleware, starman, psgi app

PSGI
13

Template Toolkit

TT2, INCLUDE_PATH, filters

TT
14

Tests (Test::More/Test2)

prove, TAP, Test::Mojo

Tests
15

Profiling & Perf

Devel::NYTProf, Benchmark

Perf
16

Debugging

perl -d, Devel::REPL

Debug
17

Unicode & Texte

binmode, utf8::all, Encode

UTF8
18

Sécurité & Taint (-T)

PATH réduit, Safe, chroot

Security
19

Scripting sysadmin

cron, journaux, glue sed/awk

Ops
20

Packaging & CI

Carton, Dockerfile, GH Actions

CI
21

XS & FFI

Inline::C, FFI::Platypus

FFI
22

Dates & Time

DateTime, Time::HiRes

Time
23

JSON/YAML/CSV

Cpanel::JSON::XS, YAML::XS

Formats
24

Email & MIME

Email::Stuffer, MIME::Lite

Mail
25

Web client

HTTP::Tiny, Mojo::UserAgent

HTTP
26

Scraping

Mojo::DOM, WWW::Mechanize

Scrape
27

Queues/Workers

Minion (Mojo), TheSchwartz

Queue
28

CLI UX

Getopt::Long::Descriptive, Term

CLI
29

Logs & Obs

Log::Any/Log4perl, Sys::Syslog

Logs
30

Références & Cheat

Docs, livres, liens utiles

Refs
TOOLCHAIN
  • Objectifs **TOOLCHAIN** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | TOOLCHAIN | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
# perlbrew
curl -L https://install.perlbrew.pl | bash
perlbrew init && perlbrew install perl-5.38.0 && perlbrew switch perl-5.38.0

# plenv
git clone https://github.com/tokuhirom/plenv ~/.plenv
~/.plenv/bin/plenv install 5.38.0 && ~/.plenv/bin/plenv global 5.38.0

# cpanm + Carton
cpanm Carton
echo 'requires "Mojolicious", "==9.45";' > cpanfile
carton install
carton exec perl -MMojolicious -e 'say $Mojolicious::VERSION'
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
BASICS
  • Objectifs **BASICS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | BASICS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use v5.36; use strict; use warnings; use utf8;
my $s = "Hello"; my @a = (1,2,3); my %h = (k=>'v');
say $h{k};
# refs
my $ar = \@a; my $hr = \%h;
say $ar->[0]; say $hr->{k};
# sub signatures
sub add($x,$y){ return $x+$y }
say add(2,40);
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
REGEX
  • Objectifs **REGEX** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | REGEX | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use v5.36; use strict; use warnings;
my $s = "user:42 email:foo@example.com";
if($s =~ /email:([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,})/){ say $1 }
# lookaround
"abc123xyz" =~ /(?<=abc)\d+(?=xyz)/ and say $&;
# named captures
"foo=99" =~ /(?\w+)=(?\d+)/; say "$+{key} -> $+{val}";
# atomic & possessive
"aaaaab" =~ /a++b/ and say "OK possessive";
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
ONE
  • Objectifs **ONE** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | ONE | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
# Compter lignes
perl -ne 'END{print $.,"\n"}' file.txt
# Extraire emails uniques
perl -ne 'print "$1\n" if /([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+)/' *.log | sort -u
# Remplacer in-place (backup)
perl -i.bak -pe 's/DEBUG\s*=\s*1/DEBUG=0/' app.conf
# JSON pretty
perl -MJSON::PP -e 'print encode_json({ok=>1})'
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
CPAN
  • Objectifs **CPAN** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | CPAN | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
cpanm Mojolicious DBI DBIx::Class Cpanel::JSON::XS YAML::XS
echo 'requires "DBI"; requires "Mojolicious";' > cpanfile
carton install
# META workflow
perl Makefile.PL && make && make test && make install
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
OOP
  • Objectifs **OOP** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | OOP | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use v5.36; use Moo;
has 'name', is=>'rw';
sub greet($self){ say "Hi, " . $self->name }
my $o = __PACKAGE__->new(name=>'Ada'); $o->greet;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
DBI
  • Objectifs **DBI** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | DBI | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use DBI;
my $dbh = DBI->connect("dbi:Pg:dbname=app","user","pass",{RaiseError=>1,AutoCommit=>1});
my $tx = eval {
  $dbh->begin_work;
  my $sth = $dbh->prepare("INSERT INTO users(name) VALUES(?) RETURNING id");
  $sth->execute("Ada");
  my ($id) = $sth->fetchrow_array;
  $dbh->commit; $id;
}; if($@){ $dbh->rollback; die $@ }
print "new id=$tx\n";
\n\n
# DBIx::Class schema (simplifié)
package My::Schema; use base 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces;
package My::Schema::Result::User; use base 'DBIx::Class::Core';
__PACKAGE__->table('users');
__PACKAGE__->add_columns(qw/id name/); __PACKAGE__->set_primary_key('id');
# usage
my $schema = My::Schema->connect('dbi:Pg:dbname=app','user','pass');
$schema->resultset('User')->create({name=>'Ada'});
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
IO
  • Objectifs **IO** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | IO | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use v5.36; use autodie; use open ':std', ':encoding(UTF-8)';
open my $fh, '<:encoding(UTF-8)', 'in.txt';
while(my $l = <$fh>){ print $l }
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
IPC
  • Objectifs **IPC** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | IPC | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use IPC::Open3; use Symbol 'gensym';
my $err = gensym;
my $pid = open3(undef, \*OUT, $err, 'ls','-la');
while(){ print } while(<$err>){ warn } waitpid $pid, 0;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
MOJO
  • Objectifs **MOJO** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | MOJO | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Mojolicious::Lite;
plugin 'Config';
under sub($c){ return 1 if $c->req->headers->header('X-Token') // '' eq 'secret'; $c->render(text=>'401',status=>401); return undef; };
get '/health' => sub ($c){ $c->render(json=>{ok=>1}) };
post '/echo'   => sub ($c){ $c->render(json=>$c->req->json) };
websocket '/ws' => sub($c){ $c->on(message=>sub($c,$msg){ $c->send("echo:$msg") }) };
app->start;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
DANCER
  • Objectifs **DANCER2** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | DANCER2 | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Dancer2; get '/hi' => sub { 'hello' }; dance;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
PSGI
  • Objectifs **PSGI** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | PSGI | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
my $app = sub {
  my $env = shift;
  return [200, ['Content-Type'=>'text/plain'], ['hello']];
};
use Plack::Builder;
builder {
  enable 'Deflater';
  enable 'AccessLog';
  $app;
};
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
TT
  • Objectifs **TT** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | TT | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
[% SET name = 'world' %]
Hello [% name | upper %]!
[% FOREACH u IN users %]- [% u.name %]\n[% END %]
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
TESTS
  • Objectifs **TESTS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | TESTS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Test::More;
use Test::Mojo;
my $t = Test::Mojo->new('MyApp'); # Mojolicious::Lite app in lib/MyApp.pm
$t->get_ok('/health')->status_is(200)->json_is('/ok'=>1);
done_testing();
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
PERF
  • Objectifs **PERF** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | PERF | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
perl -MDevel::NYTProf script.pl
nytprofhtml --open
# micro-bench
use Benchmark qw/:all/;
cmpthese(-1, { split => sub { my @x = split /,/, 'a,b,c' },
               regex => sub { 'a,b,c' =~ /(.+),(.+),(.+)/ } });
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
DEBUG
  • Objectifs **DEBUG** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | DEBUG | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
perl -d script.pl
# b (breakpoint), s / n (step/next), p expr, x \@array
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
UTF8
  • Objectifs **UTF8** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | UTF8 | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use utf8; use open ':std', ':encoding(UTF-8)'; binmode STDOUT, ':encoding(UTF-8)';
print "éàï — OK\n";
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
SEC
  • Objectifs **SEC** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | SEC | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
#!/usr/bin/env perl -T
$ENV{PATH} = '/usr/bin:/bin'; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
# Safe open
use autodie; open my $fh, '<', '/var/app/input.txt';
# Validate args
die "bad" unless ($ARGV[0] // '') =~ /^[a-z0-9_-]{1,32}$/i;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
OPS
  • Objectifs **OPS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | OPS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
# cron
* * * * * /usr/bin/carton exec -- perl /srv/app/worker.pl >>/var/log/app/worker.log 2>&1
# tail syslog
perl -MFile::Tail -e '$f=File::Tail->new("/var/log/syslog"); while(defined($l=$f->read)){print $l}'
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
CI
  • Objectifs **CI** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | CI | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
# Dockerfile
FROM perl:5.38
WORKDIR /app
COPY cpanfile* ./
RUN cpanm Carton && carton install
COPY . .
CMD ["carton","exec","plackup","-Ilib","app.psgi"]
# GitHub Actions (extrait)
- uses: shogo82148/actions-setup-perl@v1
  with: { perl-version: '5.38' }
- run: cpanm Carton && carton install
- run: prove -lr t/
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
FFI
  • Objectifs **FFI** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | FFI | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use FFI::Platypus; my $ffi=FFI::Platypus->new(api=>1);
$ffi->lib('libm.so.6');
my $cos = $ffi->function(cos => ['double'] => 'double');
print $cos->call(0.0);
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
TIME
  • Objectifs **TIME** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | TIME | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use DateTime; say DateTime->now->iso8601;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
FORMATS
  • Objectifs **FORMATS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | FORMATS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Cpanel::JSON::XS qw(encode_json decode_json);
use YAML::XS qw(Load Dump);
print encode_json({ok=>1}), "\n";
print Dump({foo=>[1,2,3]});
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
MAIL
  • Objectifs **MAIL** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | MAIL | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Email::Stuffer;
Email::Stuffer->from('x@y')->to('z@w')->subject('Hi')->text_body('ok')->send;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
HTTP
  • Objectifs **HTTP** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | HTTP | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new; $ua->inactivity_timeout(5);
say $ua->get('https://ifconfig.me')->result->body;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
SCRAPE
  • Objectifs **SCRAPE** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | SCRAPE | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Mojo::UserAgent;
my $tx = Mojo::UserAgent->new->get('https://example.com')->result;
say $_->all_text for $tx->dom->find('a')->each;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
QUEUE
  • Objectifs **QUEUE** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | QUEUE | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Mojolicious::Lite; plugin Minion => { SQLite=>'sqlite:tmp.db' };
app->minion->add_task(slow => sub ($job,$n){ sleep $n; $job->finish('ok') });
get '/enqueue' => sub ($c){ my $id = $c->minion->enqueue(slow=>[2]); $c->render(text=>$id) };
app->start;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
CLI
  • Objectifs **CLI** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | CLI | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Getopt::Long::Descriptive;
my ($opt,$usage) = describe_options('%c %o','--host=s','--port=i');
print $usage->text if $opt->help;
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
LOGS
  • Objectifs **LOGS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | LOGS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
use Log::Log4perl;
Log::Log4perl->easy_init($INFO);
my $log=Log::Log4perl->get_logger; $log->info('ok');
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;
REFS
  • Objectifs **REFS** en prod.
  • Patterns robustes.
  • Points durs & pièges.
+---------------------------+ | REFS | +---------------------------+ | CPAN | DBI | PSGI | Mojo | Regex | Tests | Perf
  • perldoc.perl.org
  • modernperlbooks.com
  • mojolicious.org
  • metacpan.org
  • dbix-class.org
  • `use v5.36; use strict; use warnings;`
  • `use autodie;` pour IO/process
  • Encodage explicite (`open` layers, `binmode`)
Tester sous 5.32/5.34/5.36/5.38 avec perlbrew/plenv.
  • Globals implicites
  • Regex gourmandes non ancrées
  • `system` sans vérification d'état
Risque de corruption, commandes zombies, injections.
KPICibleAction
Temps d’exécutionStableProfiler NYTProf
Couverture tests>=80%`prove -lr t/` + CI
Latence HTTPp95 maîtriséMojo::UserAgent + timeouts
  1. Shebang `#!/usr/bin/env perl`
  2. `strict/warnings` activés
  3. `carton install` deps verrouillées
  4. `perltidy`/`perlcritic` en CI
# t/01_basic.t
use Test::More; ok(1,'loaded'); done_testing();
# Template snippet
use v5.36; use strict; use warnings;