Les nouveautés de Perl 5.10

Sébastien Aperghis-Tramoni, sebastien@aperghis.net

Perl 5.10

  • 5.4.0 - mai 1997

  • 5.5.0 - juillet 1998

  • 5.6.0 - mars 2000

  • 5.8.0 - juillet 2002

  • ...

  • 5.10.0 - 18 décembre 2007, 20e anniversaire de Perl 1.0

  • 5.10.1 - août 2009

Ce qui a été supprimé

  • $*, $#

  • pseudo-hashes

  • compilateur

  • JPL

Syntaxe - defined-or

  • adapté de Perl 6

  • avant :

        $var = defined $input ? $input : $default;
        $option = $default unless defined $option;
  • maintenant :

        $var = $input // $default;
        $option //= $default;

Syntaxe - say

  • adapté de Perl 6

  • comme println()

  •     say "OH HAI";    # équivalent à :  print "OH HAI\n"

Syntaxe - opérations sur les fichiers

  • tests de fichiers empilables

  • adapté de Perl 6

  •     -f -w -x $file
  • opérations sur les descripteurs de fichiers

    • si supporté par l'OS

Syntaxe - smart match

  • inspiré de Perl 6

  • opérateur booléen, commutatif, noté ~~

  •     if ($a ~~ $b) {
            ...
        }
  • méthode de comparaison déterminée par le type des arguments

  • la première règle qui s'applique détermine son comportement

Syntaxe - smart match

  •   Type $a Type $b   Type de correspondance   Code équivalent
      ======= =======   ======================   ===============
      code    code      égalité des références   $a == $b
      autre   code      scalar sub truth         $b->($a)
      
      hash    hash      clés de hash identiques  [sort keys %$a]~~[sort keys %$b]
      hash    tableau   existence d'une tranche  grep {exists $a->{$_}} @$b
      hash    regex     grep des clés du hash    grep /$b/, keys %$a
      hash    autre     existence d'une entrée   exists $a->{$b}
      
      tableau tableau   tableaux identiques
      tableau regex     grep du tableau          grep /$b/, @$a
      tableau nombre    nombre dans tableau      grep $_ == $b, @$a
      tableau autre     chaîne dans tableau      grep $_ eq $b, @$a
      
      autre   undef     indéfini                 !defined $a
      autre   regex     correspondance de motif  $a =~ /$b/
      code()  code()    résultats identiques     $a->() eq $b->()
      autre   code()    simple closure truth     $b->()  # $a est ignorée
      nombre  nombre    égalité numérique        $a == $b
      autre   chaîne    égalité de chaîne        $a eq $b
      autre   nombre    égalité numérique        $a == $b 
      
      autre   autre     égalité de chaîne        $a eq $b

Syntaxe - smart match

  • basé sur une vieille spécification de Perl 6

  • différent du smart match de Perl 6 :-(

    • commutativité

    • comportement sur les tableaux

  • buggé :-(

    • ne marche pas sur les objets sans surcharge de l'opérateur ~~

    • ne se comporte pas entièrement comme documenté sur les tableaux et hashes

Syntaxe - smart match

  • corrigé dans 5.10.1

    • non commutatif

    • règle déterminée par le type de l'opérande droite

    • objets autorisés seulement si ~~ surchargé

  • ajouts

    • support des intervalles : 4.5 ~~ 3..5

    • any ~~ array distribue le test sur le tableau

Syntaxe - smart match

  •   Type $a Type $b   Type de correspondance   Code équivalent
      ======= =======   ======================   ===============
      autre   undef     non définit              !defined $a
      
      hash    coderef   code vrai pour chaque clé   !grep { !$b->($_) } keys %$a
      tableau coderef   code vrai pour chaque cas   !grep { !$b->($_) } @$a
      autre   coderef   code vrai pour la valeur    $b->($a)
      
      hash    hash      clés de hash identiques  [sort keys %$a]~~[sort keys %$b]
      tableau hash      existence d'une tranche  grep { exists $b->{$_} } @$a
      regex   hash      grep des clés du hash    grep /$a/, keys %$b
      undef   hash      toujours faux (undef ne peut être une clé)
      autre   hash      existence d'une entrée   exists $b->{$a}
      
      hash    tableau   existence d'une tranche  grep { exists $a->{$_} } @$b
      tableau tableau   tableaux identiques
      regex   tableau   grep du tableau          grep /$a/, @$b
      undef   tableau   tableau contient undef   grep !defined, @$b
      autre   tableau   distrib. du test sur tableau    grep $a ~~ $_, @$b
      
      hash    regex     grep des clés du hash    grep /$b/, keys %$a
      tableau regex     grep du tableau          grep /$b/, @$a
      autre   regex     correspondance de motif  $a =~ /$b/
      
      undef   range     toujours faux
      autre   range     dans l'intervalle
      
      autre   nombre    égalité numérique        $a == $b
      autre   autre     égalité de chaîne        $a eq $b
     -

Syntaxe - smart match

  • exemples

  •     say @a ~~ @b ? "equal" : "not equal";
  •     %a = ( plonk => "pouet" );
        $b = "plonk";
        say %a ~~ $b ? "true" : "false";    # true
  •      $a = [1, 2, 3];
         $b = 2;
         say $a ~~ $b ? "true" : "false";   # true
         $b = 5;
         say $a ~~ $b ? "true" : "false";   # false

Syntaxe - given .. when

  • inspiré de Perl 6

  •     given (EXPR) {
            when (EXPR) { ... }
            when (EXPR) { ... }
            default     { ... }
        }

Syntaxe - given .. when

  • given affecte la valeur de l'expression à $_

  • when évalue l'expression comme une condition booléenne

    • en général, équivalent à given ($_ ~~ EXPR)

  • default si rien d'autre n'a correspondu

Syntaxe - given .. when

  • contrôle du flux

    • un when qui réussit termine le given correspondant

    • break pour sortir du given

    • continue pour aller au when suivant

Syntaxe - given .. when

  • exemples

  •     given ($number) {
            when (42) { say "La Réponse"   }
            when (56) { say "fer standard" }
        }
  •     use Regexp::Common qw/net/;
    
        given ($host) {
            when ("localhost"       ) { say "adresse locale" }
            when (/$RE{net}{IPv4}/  ) { say "adresse IPv4"   }
            when (/$RE{net}{domain}/) { say "FQDN"           }
            default { say "type d'argument inconnu" }
        }

Syntaxe - variables d'état

  • adapté de Perl 6

  • nouvelle classe de variables

  • portée lexicale, mais valeur persistante

  •     sub next_power_of_two {
            state $x = 1;   # n'est affecté qu'au premier appel
            return $x <<= 1
        }
    
        say next_power_of_two() for 1..5
  • fonctionne sur les tableaux et hashes, mais sans initialisation

Syntaxe - activation

  • nouveautés désactivées par défaut pour raisons de compatibilité arrière

  • activables avec use feature ou use 5.10.0 :

        use 5.10.0;
        say "OH HAI WORLD";
  • pour les unilignes, utiliser -E :

        perl -E 'say "OH HAI WORLD"'

Syntaxe - $_ lexical

  •     for my $_ (@data) {
            ...
        }

Syntaxe - prototype _

  • similaire au prototype $ mais utilise $_ si aucune variable n'est passée en argument

Syntaxe - blocs UNITCHECK

  • similaires aux blocs CHECK, mais exécutés après la compilation de chaque unité

Syntaxe - pragmas lexicales

  • fonctionnement

    • stocke son état dans %^H à la compilation

    • le récupère à l'exécution par caller()

  • exemple : encoding::source

        use encoding::source "utf8";
        # le code écrit ici est en UTF-8
    
        {
            use encoding::source "latin-1";
            # mais celui dans ce bloc est en ISO-Latin-1
        }
    
        # et là on revient en UTF-8

Syntaxe - pragmas lexicales

  • bignum, bigint, bigrat

  • sort

  • overloading (5.10.1)

Objets

  • pas de changements fondamentaux

  • améliorations pour mieux supporter les nouveaux modèles objets

    • objets inversés (inside-out objects)

    • traits

    • rôles

    • méta-modèles

Objets - UNIVERSAL::DOES

  • méthode globale DOES()

  • facile à surcharger

  • similaire à isa(), mais plus générale et adaptée à la notion de rôle

  •     if ($dog->DOES("Walkable")) {
            $dog->walk;
        }

Objets - Hash::Util::FieldHash

  • module fourni avec Perl 5.10

  • meilleur support pour les modèles d'objets inversés

  • Hash::Util::FieldHash::Compat sur le CPAN

Objets - algorithme de résolution C3

  • terminologie

  • MRO = algorithme de résolution des méthodes

  • algorithme classique de Perl : DFS (Depth First Search)

  • pose problème pour des hiérarchies trivialement complexes

Objets - algorithme de résolution C3

  • exemple :

          A
         / \
        B   C
         \ /
          D
  • DFS renvoie : (D, B, A, C)

Objets - algorithme de résolution C3

  • algorithme de linéarisation à triple cohérence

  • garantit qu'aucune classe n'apparaît avant une de ses sous-classes

  •       A
         / \
        B   C
         \ /
          D
  • C3 renvoie l'ordre correct (D, B, C, A)

  • utilisé dans Dylan, Python 2.3, Perl 6

Objets - algorithme de résolution C3

  • DFS reste le MRO par défaut, pour raison de compatibilité

  • MRO peut être changé avec la pragma mro

  •     use mro "dfs";  # utilise le MRO DFS pour cette classe
        use mro "c3";   # utilise le MRO C3 pour cette classe
  • mro fournit aussi plusieurs fonctions et méthodes avancées

    • mro::get_linear_isa(), next::method(), next::can()

Objets - algorithme de résolution C3

  • MRO::Compat et Class::C3 sur le CPAN

  • fournit l'algorithme sur Perl 5.8

  • utilise celui natif sur Perl 5.10

  • mro fournit une API interne de plugin dans 5.10.1

Optimisations

  • beaucoup de refactoring interne

  • factorisation de structures internes

  • gain de mémoire

  • constantes plus légères

  • constant sur le CPAN et disponible pour Perl 5.5

Optimisations

  • cas particuliers de sort

    •     @a = sort @a   # plus de liste intermédiaire
    •     reverse sort ...   # trie à l'envers
  • fonction de tri peut être récursive

Optimisations

  • Unicode : opérations améliorées

  • Unicode : meilleure utilisation du cache

  • création des références de tableau et hash plus rapide

Sécurité

  • $AUTOLOAD respecte le taint mode

  • printf() et sprintf() rejettent les arguments non valides

  • utilisation de strlcat() et strlcpy()

  • constification de l'API interne et externe

    • char * => const char *

Modules - nouveaux modules dans le core

  • Module::CoreList, corelist

  • Archive::Tar, Compress::Zlib

  • Module::Pluggable, Pod::Simple

  • encoding::warnings

  • ExtUtils::ParseXS, ExtUtils::CBuilder

  • Module::Build, CPANPLUS

  • autodie, parent

Modules - nouveaux modules à double vie

  • Exporter, File::Path

  • constant, Pod::Html

Divers

  • diagnostics plus explicites (quand c'est possible)

    • Use of uninitialized value $w in print at -e line 1.

  • base Unicode 5.0.0 (5.10.0)

  • base Unicode 5.1.0 (5.10.1)

Portabilité

  • meilleur support pour les OS exotiques

  • OS EBCDIC : OS/390, z/OS, etc

  • OpenVMS : support d'ODS-5

  • Win32 :

    • support des noms Unicode (sur NTFS)

    • optimisation de stat() (variable ${^WIN32_SLOPPY_STAT})

Article

Questions ?

Merci