Les nouveautés de perl 5.10

Les nouveautés de perl 5.10

David Landgren
<david@landgren.net>

Fondateur, Paris Perl Mong(u)e\R1rs

Ce à quoi il faut (?:s')?attendre

  • ce qu'on retire

  • ce qu'on change

  • ce qu'on améliore

  • ce qu'on ajoute

Ce qu'on retire

Variables prédéfinies

Certaines variables globales obsolètes (dépréciées en 5.8) ont été supprimé

  • $# - format de sortie des nombres

  • $* - recherche multilignes

Comment vivre sans $# ?

Ça ne marchait plus depuis au moins 5.005_03

  $# = shift if @ARGV;
  print $_ / 7, $/ for 20..23;
  sans $#             avec $# = 5
  2.85714285714286    5
  3                   5
  3.14285714285714    5
  • avertissement depuis 5.6

  • utiliser sprintf

Comment vivre sans $* ?

  my $str = "foo\nbar";
  $* = 0; print "ok 1\n" if $str =~ /o.b/;
  $* = 1; print "ok 2\n" if $str =~ /o.b/;
          print "ok 3\n" if $str =~ /o.b/s;

Produit ok 3

  • utiliser /m et /s explicitement sur l'expression régulière qui en a besoin.

  • Gestion plus fine, moins d'effets de bord

L'attribut :unique

  • ne sert que pour les variables our

  • dans un environnement multi-interpreteur

  • garanti l'existence d'une seule copie de cette variable à travers tous les interpreteurs

  • trop de race conditions, impossibles à corriger

  • il faut réflechir à une autre implementation

perlcc, le compilateur bytecode

  • ne marchait pas

  • n'avait plus de champion

  • n'a pas suivi les restructurations du core

  • grande source de bugs, gourmand en suivi

JPL, la passerelle Java-Perl

  • ne marchait pas

  • n'avait plus de champion

  • n'avait pas d'utilisateurs non plus

Ponie (flogging a dead horse)

  • Perl 5 sur Parrot

  • sponsorisé par Fotango

  • Nicholas Clark fait autre chose

  • pas d'autres volontaires

  • une certaine influence sur blead

goto dit magic dans un eval

On ne peut plus faire

  eval { goto &fonction }
  • conséquence de la restructuration de l'intérpreteur

  • c'était Mal de toute façon

Ce qu'on change

v-strings en tant que clés de hash

Depuis perl 5.6 jusqu'à perl 5.8.8:

  my %h => (v65 => 'alpha');
  print "$_: $h{$_}\n" for keys %h;

produit

  A: alpha

v-strings en 5.10

En 5.10, le même code:

  my %h => (v65 => 'alpha');
  print "$_: $h{$_}\n" for keys %h;

produit

  v65: alpha

Variables lexicales statiques

Définition d'un my avec un statement modifier

  my $statique if 0;
  • crée une variable statique dans une routine (au sens C)

  • ne marchait pas dans tous les cas

  • tendance à surprendre le programmeur

  • maintenant cette construction génère un avertissement (warning)

  • se fait autrement dans 5.10

Routines constants

 use constant PI => 22/7;
  • l'implémentation des routines constant a changé

  • utilise moins de mémoire

  • surtout si le constant n'est jamais référencé dans le code

  • 'use POSIX' économise 200 kilo octets

  • attention pour les auteurs de modules en XS

  • there's only one official way to do it

Tainting

  • mécanisme d'auto-défense

  • $AUTOLOAD devient suspect

  • le paramètre format de printf et famille (la chaîne '%02d') aussi

bison remplace byacc

Le parseur de Perl (qui traite le source d'un programme Perl)

  • est maintenant généré par bison

  • le résultat à l'air plus robust

Ce qu'on améliore

$_ par défaut

Maintenant, unpack peut utiliser $_ implicitement:

  $_ = 'W X Y Z';
  my @a = unpack('a a a a');

Et mkdir aussi.

  mkdir for @ARGV;
  • par principe d'orthogonalité

  • les autres le font

Opérations sur file handles

 open my $fd, '>', 'new.script';
 print $fd "vigor NEXT Hugi ammolite Brian slops\n";
 chmod 0777, $fd;
 close $fd;
  • ls -l du fichier donne -rwxrwxrwx

  • chdir et chown (si root) également

Unicode Character Database (UCD)

Perl est livré avec la version 4.0.0 du UCD

Par exemple, Le property name \N{HANGUL SYLLABLE BEU} représente le codepoint 0xBE0C.

Pour plus d'information : http://www.unicode.org/ucd/

Unicode Character Database (UCD)

Perl est livré avec la version 4.0.0 du UCD


Perl est livré avec la version 4.0.1 du UCD (perl 5.9.2)

Unicode Character Database (UCD)

Perl est livré avec la version 4.0.0 du UCD


Perl est livré avec la version 4.0.1 du UCD (perl 5.9.2)


Perl est livré avec la version 4.1.0 du UCD (perl 5.9.3)

Unicode Character Database (UCD)

Perl est livré avec la version 4.0.0 du UCD


Perl est livré avec la version 4.0.1 du UCD (perl 5.9.2)


Perl est livré avec la version 4.1.0 du UCD (perl 5.9.3)


Perl est livré avec la version 5.0.0 du UCD (perl 5.9.5).

Améliorations Unicode et UTF-8

  • /i, lc et uc sont plus rapides

  • character classes pour Unicode

  • sprintf, chop, chomp, join et substr gèrent mieux les chaînes en UTF-8

  • changements semantiques pour pack/unpack

  • le cache UTF-8 plus efficace, utilisé plus souvent

Tris sur place

Une instruction telle que

  @tab = sort @tab
  • en 5.8, créait une liste temporaire

  • maintenant le tri se fait sur le tableau directement

  • pas de copie de résultat temporaire

  • in-place sort

Tris inverses

  reverse sort @tab
  • maintenant cela fait un tri descendant

  • plus de liste intermédiaire

  • de manière générale, sort utilise moins de mémoire

  • quelques améliorations mineures pour la vitesse

Tris recursifs

  @ordre = sort fonction @chaos;
  • la routine 'fonction' peut s'appeller recursivement

  • utile pour trier des arbres

map en contexte void

Une instruction telle que

  map { print $_ * 2 } @tableau;
  • en 5.8, générait une liste, aussitôt mis au rebut

  • en 5.10, perl detecte si le résultat est nécessaire

  • ne génère pas de liste en l'absence d'affectation

  • c'est pas pour autant qu'il faut en abuser

Tests sur fichiers via _

  sub _ { print "ook!\n" }
  print "pr\xe9sent\n"
    if -e $0 and -f _;
  • jusqu'à 5.8.x, produit 'ook!'

  • dans 5.10, produit 'présent'

  • mais un sub nommé _ est Mal

Structures internes plus petites

Le plupart des struct C ont suivi une cure de minceur. Sur un processeur 32 bits:

  • OP (une instruction bytecode) : 4 octets de moins

  • XPVNV (nombre virgule flottant) : 4 en moins

  • XPVMG (magique) : 4 en moins

  • XPVAV (un tableau) : 16 octets en moins

  • XPVHV (un hash) : 20 octets en moins

  • XPVGV (un glob) : 24 octets en moins

Structures internes (suite)

  • compensé par d'autres struct qui gagnent un peu

  • SV, AV, HV et similaire passe de 12 à 20.

  • mais au total il y a une nette reduction

  • XPVMG, XPVAV, XPVHV, et XPVGV sont tous 32 octets sur un CPU 32 bits

  • les caches L2 apprécieront

Listes et hashes

Creation de listes et hashes anonymes

  my $tab   = [2, 3, 5, 8, 13, 21];
  my $assoc = {
    lipsinc => 1,
    saturday => 2,
    argo => 3
  };
  • avant, cela necessitait 3 op-codes

  • maintenant, plus qu'un seul

Listes et hashes (avant)

my $anon = [321, 456];

 a  <@> leave[1 ref] vKP/REFC ->(end)
 1     <0> enter ->2
 2     <;> nextstate(main 1 anonhash:1) v ->3
 9     <2> sassign vKS/2 ->a
 7        <1> srefgen sK/1 ->8
 -           <1> ex-list lKRM ->7
 6              <@> anonlist sKRM/1 ->7
 3                 <0> pushmark s ->4
 4                 <$> const(IV 321) s ->5
 5                 <$> const(IV 456) s ->6
 8        <0> padsv[$anon:1,2] sRM*/LVINTRO ->9

Listes et hashes (après)

my $anon = [321, 456];

 9  <@> leave[1 ref] vKP/REFC ->(end)
 1     <0> enter ->2
 2     <;> nextstate(main 1 anonhash:1) v:{ ->3
 8     <2> sassign vKS/2 ->9
 6        <@> anonlist sK*/1 ->7
 3           <0> pushmark s ->4
 4           <$> const(IV 321) s ->5
 5           <$> const(IV 456) s ->6
 7        <0> padsv[$anon:1,2] sRM*/LVINTRO ->8

Tests sur fichiers empilables

  print "présent\n"
    if -e -f $0;
  • jusqu'à 5.8, produit rien

  • au moins il n'y avait pas d'erreur

  • cependant, un message aurait été peut-être utile

  • dans 5.10, produit 'présent'

  • syntax libéré de Perl 6

Ce qu'on ajoute

L'opérateur defined-or

  $x // $y

équivalent à

  (defined $x ? $x : $y)

Difference par rapport à ||

Avec || (ou logique), risque de se tromper

  sub truc {
    my $valeur = shift || 10;
    print $valeur * 2;
  }
  truc(17) # imprime 34
  truc()   # imprime 20
  truc(0)  # imprime 20

Difference par rapport à || (suite)

Avec || (ou logique), plus de risque

  sub truc {
    my $valeur = shift // 10;
    print $valeur * 2;
  }
  truc(17) # imprime 34
  truc()   # imprime 20
  truc(0)  # imprime 0

Variables d'état

Pour déclarer des variables statiques dans une routine à la C

  • state $var = 10;

  • et state @liste = (2, 3, 5, 7, 11, 13);

  sub counter {
    state $var = 1;
    return $var++;
  }
  print counter();
  print counter();

$_ lexicale

  $_ = 10;      print "a $_\n"; # a 10
  { my $_ = 14; print "b $_\n"; # b 14
    { our $_;   print "c $_\n"; # c 10
      $_ = 18;  print "d $_\n"; # d 18
    }           print "e $_\n"; # e 14
    $_ = 20;    print "f $_\n"; # f 20
  }             print "g $_\n"; # g 18
  • map et for savait créer des $_ lexicales

  • print "$_\n" for map { $_ * 2 } 2..4;

  • print $_ affichera 18 à nouveau

  • maintenant tout le monde peut faire autant

Le prototype _

  sub gluttony (_) {
    my $arg = shift;
    print "arg = $arg\n";
  }
  $_ = 'malachite';
  gluttony('molestiae');
  gluttony();
  • on peut indiquer qu'un routine opère sur $_ par défaut

  • et perl fournira le contenu en cas de besoin

  • plus facile d'imiter des "built-ins"

Le bloc UNITCHECK

  • code qui est executé une fois que le package ou fichier a été compilé.

  • s'appelle CHECK en Perl 6

  • mais CHECK existe déjà en Perl 5, et fait autre chose

  • et le fait mal

  • avec UNITCHECK, la vie est belle

x (répetition) sur une liste qw

On pouvait utiliser l'opérateur x sur un scalaire :

  my $str = 'a' x 3;
  # aaa

Maintenant on peut l'utiliser sur une liste aussi :

  my @arr = qw(x y z) x 3
  # x y z x y z x y z
  • mais pas @arr = @x x 3;

Les nouveaux dispositifs

Certaines nouvelles fonctionnalités sont accessible uniquement en tant que features.

  • use feature 'foo';

  • -E correspond à -e avec tout les features activés

  • nouveau syntaxe, mots clés "faibles" (weak keywords)

feature 'say'

  • équivalent à 'print' avec un "\n" implicite

  • syntaxe libéré de Perl 6

feature 'err'

  • '$x err $b' est équivalent à '$x // $y'

  • précedence moindre

  • par souci de équivalence Perl 6

  • les porters le detestent

  • donc ils ont également ajouté 'dor' (defined-or)

  • Larry Wall pense que "dor is dorky" (débile)

feature 'switch'

  • n'est pas un source filter

  • donc ça marche

  • syntaxe libéré de Perl 6

  • given et when complètent le tableau

  • quelques nuances mineures de comportement

  • donc pas 100% compatible avec Switch.pm

feature 'smart match'

  use feature '~~';
  my %h = ( a => 2, b => 9 );
  my $g = { a => 2, b => 9 };
  my @j = qw(a b);
  print %h ~~ %$g; # 1
  print %h ~~ @j;  # 1 aussi
  • comparaison entre tout et n'importe quoi

  • syntaxe libéré de Perl 6

  • tout est dans perlsyn

Les expressions régulières

  • l'implémentation n'est plus recursive

  • le moteur a été restructuré en profondeur par Dave Mitchell et Yves Orton

  • alternatives examinés via une structure de trie

  • optimisation Aho-Corasick (où commencer à chercher)

  • (?=...) n'est plus ignoré par l'optimisateur

Les expressions régulières (suite)

  • /[a]/ optimisé en /a/

  • certaines contructions marquées experimental ne le sont plus

  • (?{...}) et (??{...}) le sont toujours

  • quantifieurs possessifs avec ++

  • ('aaaa' =~ /a++a/) échoue

Regexps : références relatives

Avec \Rn on compte n parenthèses en arrière.

  'ddee' =~ /(.)\R1(.)\R1/ and print "$1 $2"; # d e
  'deed' =~ /(.)(.)\R1\R2/ and print "$1 $2"; # d e
  • au lieu de compter à partir de 1, on revient en arrière

  • pratique si on capture un nouvel élément au milieu plus tard

Regexps : captures nommés

  /Paris (?<cp>[0-9]+)/
  print "code postal = $+{cp}\n";
  • au lieu de compter à partir de 1, on nomme la chose qu'on veut récupérer

  • pratique si on capture un nouvel élément au milieu plus tard

  • la variable %+ contient les captures (comme @+)

  • diminution des recours à (??{...})

Regexps : back references nommés

  print "simile detected!"
    if "as easy as pie" =~
      /(?<as>as) (\w+) \k<as> (\w+)/;
  • au lieu d'énumérer une reference, on le nomme

  • et on fait réference au nom

  • je crois que j'ai trouvé un bug (ça marche pas)

Regexps : Parser XML avec un regexp!

  • recherches recursifs via (?1) au lieu de (??{...})

  • a priori possible, mais je n'ai pas réussi

  • lire perlre.pod pour plus d'infos

  • quelque chose de nouveau chaque semaine

Regexps : affiner le backtracking

De nombreux "verbes" ont été ajouté pour affiner le comportement du moteur lors d'un échec partiel.

  • THEN

  • PRUNE

  • MARK

  • SKIP

  • COMMIT

  • FAIL

  • ACCEPT

Regexps : les verbes de contrôle

Le verbe (?ACCEPT) avait l'air étrange. Comme (* générait un erreur de syntaxe, on écrit (*ACCEPT) (et pareil pour tous les autres).

  • rules

  • 6 on 5

  • pluggable engines (PCRE)

  • je n'ai encore rien compris

Compilation en C++

  • grand effort de la part de Jarkko Hietaniemi

  • perl se compile avec g++ et autres compilateurs de C++

  • met en evidence des pratiques douteuses

Utilisation de const

  • grand effort de la part d'Andy Lester

  • rend const tout ce qui est possible

  • a corrigé quelques bugs

  • permet de soulever des erreurs lors la compilation

suidperl plus sécurisé

  • de nombreux failles ont été comblé

  • mais il ne faut pas s'en servir

  • sudo marche mieux

Nouvelles pages de documentation

  • perlpragma - informations sur les pragmas

  • perlreguts - informations sur les internals du moteur des expressions régulières

  • perlunitut - une introduction à Unicode dans Perl

Nouveaux pragmata

  • assertions

  • encoding::warnings

  • feature

  • version

Nouveaux modules

(Liste non exhaustive)

  Archive::Tar           Module::Build
  Compress::Zlib         Module::Load
  Config::Extensions     Module::Loaded
  Digest::SHA            Moped::Msg
  Hash::Util::FieldHash  Package::Constants
  IO::Compress           Pod::Escapes
  IO::Uncompress         Pod::Simple
  IO::Zlib               Win32API::File
  Math::BigInt::FastCalc

D'autres améloriations

  • dernières versions des modules

  • plus de platformes supportés ou améliorés (VMS)

  • moins de fuites avec les closures, lexicales et eval

  • compilation du binaire perl en parallèle

  • mais pas la suite des tests (encore)

  • Misc Attribute Decoration (MAD)

D'autres améloriations

  • assertions

  • unsafe signals disponible à nouveau

  • SIGILL, SIGBUS et SIGSEGV sont livrés unsafely

  • portée localisé des pragmas (e.g. sort)

C'est pour quand ?

  • 5.7.0 septembre 2000

  • 5.8.0 juillet 2002

  • 5.9.0 octobre 2003 (Hugo van der Sanden)

  • 5.9.1 mars 2004 (Rafael Garcia-Suarez)

  • 5.9.4 aout 2006

C'est pour quand (suite) ?

  • perl 5.9.5 d'ici un mois ou deux

  • les porters ont dit ce qu'ils veulent faire avant 5.10.0

  • premier Release Candidate viendra après

  • installer un bleadperl est facile

  • /usr/local/bin/perl5.9.x n'écrase rien

  • tester vos modules, surtout ceux avec du XS

Questions

Merci