• [^] # Perl or not Perl

    Posté par (site web personnel) . En réponse au journal écriture d'un script AWK de transformation de Markdown en HTML. Évalué à 6.

    Merci pour cette longue description qui permettra à tout un chacun chacune d'estimer son appétence envers la syntaxe Perl. Pour ma part 🤢

    J’ai plus fait le tour des particularités à connaître quand on vient d’un autre langage que des trucs sympas.

    Par exemple, si on veut un tableau d’entiers allant de 1 à 10 : my @t = 1 .. 10;

    Il y a des choix inusuels qui permettent une certaine souplesse.
    Par exemple, si une fonction attend des paramètres fixes et un nombre variable d’autres paramètres, on peut les récupérer avec my ($a, $b, $c, @val) = @_;

    Il y a certaines fonctionnalités bien pratiques, comme la fonction map, qui remplace ses arguments par le résultat du bloc de commandes ou de la chaîne passée en premier paramètre, appliquée à chacun un par un, et retourne cela en liste. C’est plus court et moins lourd à lire qu’un for avec un ajout dans un tableau. Mais on ne commence pas forcément par ça en venant d’un autre langage.
    C’est moins gratifiant de commencer par s’assurer de pouvoir faire ce qu’on savait déjà faire dans d’autres langages, mais ça cause sûrement moins de frictions.

    #!/usr/bin/perl -w
    use strict;
    # ax2 + bx + c
    sub f {
     my ($a, $b, $c, @val) = @_;
     return map { $a * $_ ** 2 + $b * $_ + $c } @val;
    }
    print map "$_\n", f(2, 3, 1, 1 .. 10);

    Je m'en tiendrait à la maxime

    Ne le fait pas avec Python si tu peux le faire avec Perl

    Bonne idée : du coup, il n’y a aucune raison d’utiliser Python ;-) (OK, NumPy).
    En plus, ça évite de devoir se coltiner des virtualenv parce que la bibliothèque truc nécessite la bibliothèque bidule 15, mais ne fonctionne pas avec la 16, parce que la notion de compatibilité ascendante n’a malheureusement pas pénétré l’écosystème Python.

    Ne le fait pas avec Perl si tu peux le faire avec Awk

    Je regrette vraiment qu’AWK ait été cantonné à du parcours de fichier. À mon sens, il aurait mérité de remplacer le shell.

    Ne le fait pas avec Awk si tu peux le faire avec Sed

    Oui, enfin au delà de la substitution, sed devient vite ésotérique (un peu entre les CSS et la configuration de sendmail). Utiliser sed à fond disqualifie pour se plaindre de la lisibilité de Perl.

    Ne le fait pas avec Sed si tu peux le faire avec Grep

    Bon, j’utilise aussi grep pour les cas triviaux.

    J’ai des collègues qui pensent comme ça aussi.
    Le problème, c’est que parfois les besoins évoluent.

    On commence à faire un truc en shell en « pipant » des commandes, et on s’aperçoit que ce serait bien de traiter une autre donnée en parallèle, sauf que ce n’est pas très pratique à faire dans des pipes, et donc on finit par refaire le traitement dans un vrai script avec une logique très différente.

    Ou on commence par écrire un script shell, puis on le complexifie jusqu’au stade où on se dit que ce n’est pas très pratique ou très rapide (n’importe quel langage qui n’appelle pas des programmes externes pour des commandes de base est beaucoup plus rapide que le shell) et qu’on ferait mieux de le refaire en Python.

    Alors que Perl est évolutif. Tu commences par une uniligne pas plus longue que celle avec des pipes (en utilisant les options comme -n et sans déclarer les variables). Puis s’il tu dois passer à un vrai script, tu ajoutes use strict;, tu déclares les variables, tu remplaces les options par leur équivalent explicite, mais tu n’as pas à refaire ton code, juste à le compléter. Et si un script doit devenir plus complexe, pas besoin de changer de langage, tu as déjà un langage bien plus puissant que le shell.

    Et j'ajouterai que AWK faisant partie du standard Posix, cela en fait une dépendance sur laquelle on peut quasiment toujours compter, même dans des environnements restreints.

    Attention, awk, c’est comme l’eau Cristaline, ce ne sont pas tous le même. Et certaines fonctionnalités utiles ne font pas partie de la version de base.

    Commet le shell et contrairement à tous les autres langages de scripts.

    C’est pire pour le shell. Si tu ne sais pas si ton script sera exécuté sur bash ou sur un vieux ksh même pas Posix (la dernière fois que j’ai essayé OpenIndiana, c’était le cas de son /bin/sh, pour ne pas casser la compatibilité de vieux scripts écrits il y avait déjà plusieurs décennies), ça limite beaucoup.

    Et il y a des « bashismes » qui sont vraiment utiles, comme "$@" (j’ai remplacé les dollars par leur version mini dans ce paragraphe, parce qu’autrement, Markdown me remplace la suite par du Mathjax ou au mieux par la chaîne {mathjax} quand je tente de le quoter avec \ ; seule une lettre derrière le dollar semble empêcher ce comportement pénible) pour passer les arguments de la fonction courante à une autre fonction ou commande sans connaître leur nombre et sans se prendre un gros bug si certains contiennent des espaces. Les shells moins évolués ne disposent que de $*. Tel quel, il met tous les arguments dans la ligne de commande sans guillemets, et "$*" les passe tous comme un seul argument entre guillemets. Dans les deux cas, s’il y en avait qui contenaient des espaces, il n’y a plus moyen de les séparer de manière fiable. Alors que "$@" fait comme s’ils étaient passés chacun entre guillemets. C’est moins logique par rapport à la syntaxe, mais c’est le comportement dont on a réellement besoin.

    Si on en vient à devoir installer bash, autant installer Perl.

    Prendre une bonne disposition : beop.free.fr