DéveloppeurWeb.Com
    DéveloppeurWeb.Com
    • Agile Zone
    • AI Zone
    • Cloud Zone
    • Database Zone
    • DevOps Zone
    • Integration Zone
    • Web Dev Zone
    DéveloppeurWeb.Com
    Home»Open Source Zone»Better Perl : 4 bonnes pratiques de traitement de liste avec Map, Grep, etc.
    Open Source Zone

    Better Perl : 4 bonnes pratiques de traitement de liste avec Map, Grep, etc.

    octobre 26, 2021
    Better Perl : 4 bonnes pratiques de traitement de liste avec Map, Grep, etc.
    Share
    Facebook Twitter Pinterest Reddit WhatsApp Email
    Fille avec une carte

    Il y a six mois, j’ai donné un aperçu des principes fondamentaux du traitement des listes de Perl, décrivant brièvement ce que sont les listes, puis présentant le map et grep fonctions pour les transformer et les filtrer. Plus tard, j’ai compilé une liste (si appropriée) des modules de traitement de liste disponibles via CPAN, en notant qu’il y a une duplication d’effort déroutante. Mais vous êtes un développeur occupé et vous voulez simplement connaître la bonne chose à faire™ face à un défi de traitement de liste.

    Tout d’abord, un certain mérite est dû : ce sont toutes des reformulations de plusieurs politiques de Perl::Critic qui à leur tour codifient les normes décrites dans Damian Conway Meilleures pratiques Perl (2005). J’ai recommandé à plusieurs reprises ce dernier comme point de départ pour un développement Perl de meilleure qualité. Au fil des ans, ces pratiques continuent d’être réévaluées (y compris par l’auteur lui-même) et divers auteurs publient de nouveaux modules de politique, mais perlcritic reste un excellent outil pour vous assurer (ainsi que votre équipe ou d’autres contributeurs) de maintenir un niveau élevé et constant dans votre code.

    Cela dit, passons aux recommandations !

    Ne pas utiliser grep pour vérifier si Tout Correspondance des éléments de la liste

    Cela peut sembler étrange de commencer en recommandant ne pas utiliser grep, mais parfois ce n’est pas le bon outil pour le travail. Si vous avez une liste et que vous souhaitez déterminer si une condition correspond à un élément, vous pouvez essayer :

    if (grep { some_condition($_) } @my_list) {
        ... # don't do this!
    }

    Oui, cela fonctionne parce que (dans un contexte scalaire) grep renvoie le nombre de correspondances trouvées, mais c’est du gaspillage, en vérifiant chaque élément de @my_list (ce qui peut être long) avant de finalement fournir un résultat. Utilisez le module standard List::Util any fonction, qui renvoie immédiatement (« court-circuits ») à la première correspondance :

    use List::Util 1.33 qw(any);
    
    if (any { some_condition($_) } @my_list) {
        ... # do something
    }

    Perl a inclus la version requise de ce module depuis la version 5.20 en 2014 ; pour les versions antérieures, vous devrez effectuer une mise à jour à partir du CPAN. List::Util a de nombreuses autres fonctions de réduction de liste, de paire clé/valeur et d’autres fonctions connexes que vous pouvez importer dans votre code, alors vérifiez-les avant d’essayer de réinventer des roues.

    En guise de remarque pour les développeurs Web, le framework Perl Dancer comprend également un any mot-clé pour déclarer plusieurs routes HTTP, donc si vous mélangez List::Util là-dedans, ne l’importez pas. Au lieu de cela, appelez-le explicitement comme ceci ou vous obtiendrez une erreur sur une fonction redéfinie :

    use List::Util 1.33;
    
    if (List::Util::any { some_condition($_) } @my_list) {
        ... # do something
    }

    Cette recommandation est codifiée dans la politique BuiltinFunctions::ProhibitBooleanGrep Perl::Critic, vient directement de Meilleures pratiques Perl, et est recommandé par la norme de codage Perl du Software Engineering Institute Computer Emergency Response Team (SEI CERT).

    Ne change pas $_ dans map ou grep

    Je l’ai mentionné en mars, mais il convient de le répéter : map et grep sont conçus comme des fonctions pures, et non comme des mutateurs avec des effets secondaires. Cela signifie que la liste d’origine doit rester inchangée. Oui, chaque élément aliase à son tour le $_ variable spéciale, mais c’est pour la vitesse et peut avoir des résultats surprenants si elle est modifiée même si cela est techniquement autorisé. Si vous devez modifier un tableau sur place, utilisez quelque chose comme :

    for (@my_array) {
        $_ = ...; # make your changes here
    }

    Si vous voulez quelque chose qui regards Comme map mais ne changera pas la liste d’origine (et cela ne vous dérange pas quelques dépendances CPAN), considérez List :: SomeUtils’ apply fonction:

    use List::SomeUtils qw(apply);
    
    my @doubled_array = apply {$_ *= 2} @old_array;

    Enfin, les effets secondaires incluent également des choses comme la manipulation d’autres variables ou l’entrée et la sortie. Ne pas utiliser map ou grep dans un contexte vide (c’est-à-dire sans tableau ou liste résultant) ; faire quelque chose avec les résultats ou utiliser un for ou foreach boucle:

    map { print foo($_) } @my_array; # don't do this
    print map { foo($_) } @my_array; # do this instead
    
    map { push @new_array, foo($_) } @my_array; # don't do this
    @new_array = map { foo($_) } @my_array; # do this instead

    Cette recommandation est codifiée par les politiques BuiltinFunctions::ProhibitVoidGrep, BuiltinFunctions::ProhibitVoidMap et ControlStructures::ProhibitMutatingListFunctions Perl::Critic. Ce dernier vient de Meilleures pratiques Perl et est une règle SEI CERT Perl Coding Standard.

    Utiliser des blocs avec map et grep, pas des expressions

    Tu peux appeler map ou grep comme ceci (les parenthèses sont facultatives autour des fonctions intégrées) :

    my @new_array  = map foo($_), @old_array; # don't do this
    my @new_array2 = grep !/^#/, @old_array;  # don't do this

    Ou comme ça :

    my @new_array  = map { foo($_) } @old_array;
    my @new_array2 = grep {!/^#/} @old_array;

    Faites-le de la deuxième façon. C’est plus facile à lire, surtout si vous transmettez une liste littérale ou plusieurs tableaux, et les formes d’expression peuvent cacher des bogues. Cette recommandation est codifiée par les politiques BuiltinFunctions::RequireBlockGrep et BuiltinFunctions::RequireBlockMap Perl::Critic et provient de Meilleures pratiques Perl.

    Refactoriser l’instruction multiple maps, greps et autres fonctions de liste

    map, grep, et les amis devraient suivre la philosophie Unix de « Do One Thing and Do It Well ». Votre lisibilité et votre maintenabilité diminuent avec chaque déclaration que vous placez dans l’un de leurs blocs. Considérez les développeurs juniors et les futurs mainteneurs (cela vous inclut !) for boucle. Cela vaut pour les fonctions de traitement de liste (comme les any également importé d’autres modules.

    Cette recommandation est codifiée par le Meilleures pratiques Perl-inspired BuiltinFunctions::ProhibitComplexMappings et BuiltinFunctions::RequireSimpleSortBlock Perl::Critic politiques, bien que celles-ci ne couvrent que map et sort fonctions, respectivement.


    Avez-vous d’autres suggestions pour les meilleures pratiques de traitement des listes ? N’hésitez pas à les laisser dans les commentaires ou mieux encore, envisagez de créer de nouvelles politiques Perl::Critic pour eux ou de contacter l’équipe Perl::Critic pour les développer pour votre organisation.

    Share. Facebook Twitter Pinterest LinkedIn WhatsApp Reddit Email
    Add A Comment

    Leave A Reply Cancel Reply

    Catégories

    • Politique de cookies
    • Politique de confidentialité
    • CONTACT
    • Politique du DMCA
    • CONDITIONS D’UTILISATION
    • Avertissement
    © 2023 DéveloppeurWeb.Com.

    Type above and press Enter to search. Press Esc to cancel.