Logo des Mongueurs de Perl

Des nouveaux, mais aussi le retour de grands anciens

Un historique de toutes nos réunions

 
 

Table des matières

mercredi 07 mars 2001

La voix du secrétaire (Jean)
Présents à cette réunion : Éh oui, il y a deux David, deux Nicolas et deux Philippe. Du coup, je vais être obligé de préciser David (L) ou David (R), Nicolas (J) ou Nicolas (C), et Philippe (B) ou Philippe (B). Euh, Philippe (Br) et Philippe (Br). Enfin, Philippe /Br.*t/ et Philippe /Br.*t/. Bon, je vais dire BooK ou brix.
En outre, il convient de noter que, outre les mets et breuvages énumérés ci-dessus, nous avons eu droit à de la Tomme de Savoie offerte par Bernard, et à une boîte de chocolats apportée par Philippe (BooK).

Nous avons parlé des statuts de l'association, de programmation Perl, de nos dernières découvertes sur Internet et de sujets divers.

Les Mongueurs de Perl

  • Depuis la dernière réunion, l'association a beaucoup progressé sur la liste YAPC-Paris. Dans l'immédiat, il y a besoin d'un président, d'un secrétaire, et il faut également rédiger les statuts. Il n'y a pas besoin tout de suite d'avoir un trésorier, et de plus le trésorier n'est pas nécessairement membre de l'association. Il sera nécessaire de pourvoir ce poste au moment où l'association ouvrira un compte, ce qui aura lieu après le dépôt et l'enregistrement des statuts. Donc, pour l'instant, le président est David (L), et le secrétaire, c'est moi. Il y aura une assemblée générale au mois de décembre. Si d'autres volontaires se présentent, ils pourront postuler à l'un de ces postes à ce moment-là.
  • Briac a apporté la dernière mouture des statuts. Il s'est arrangé pour ne pas engendrer de restrictions trop importantes. En effet, il se peut que certaines activités qui ne nous paraissent pas utiles à l'heure actuelle, voire auxquelles nous n'avons pas encore pensé, se révèlent dans la ligne de l'activité des Mongueurs de Perl. Par exemple, les statuts font mention des immeubles que l'association pourrait détenir...

    Perl

  • Nous avons parlé du concours de démineur. Il y a quelque temps, Slashdot avait évoqué un article selon lequel la résolution d'un problème de démineur est NP-complet. Par conséquent, ce n'est pas en Perl qu'il faut coder un tel programme, mais avec une machine de Turing, puisque traditionnellement, toutes les études sur les problèmes NP-complets s'appuient sur la machine de Turing.
  • Certains (dont je tairai le nom) évoquent des moyens un peu moins algorithmiques et un peu moins orthodoxes de résoudre le problème. Par exemple, examiner le contenu du "fichier" /proc/kmem.
  • Il paraît que Philippe (BooK) a l'intention d'écrire un programme de démineur avec uniquement des regexps (c'est l'autre Philippe, brix qui l'assure). Et pourquoi pas, après tout, certains écrivent un assembleur en bash, d'autres un file system en Perl, d'autres encore un "Hello world" en Intercal...
  • J'évoque un autre concours, qui a eu lieu dans le tout premier numéro de The Perl Journal, basé sur un article par Douglas Hofstadter dans Scientific American en mai 1983 (entre autres). Il s'agit du dilemme du prisonnier, dont l'énoncé est le suivant. Une variante intéressante en programmation consiste à itérer le dilemme, avec deux programmes simulant chacun un prisonnier. À l'itération n, le programme simulant un prisonnier ne sait pas quelle est la réponse de son complice pour cette itération, mais il sait ce qu'il a répondu au cours des n - 1 itérations précédentes. Il sait notamment si le complice a tendance à trahir ou à coopérer.
    À noter que ce problème n'a rien à voir avec des bulles de chewing-gum de 2 mètres de diamètre, avec un village appelé Port-Meirion ou avec un acteur appelé Patrick McGoohan.
    À noter également que les articles que Douglas Hofstadter a écrit pour Scientific American sont compilés dans Mathemagical Themas (traduction française, Ma Thémagie, Inter Éditions).
  • Emmanuel nous a narré ses débuts avec Perl. Un de ses professeurs lui avait demandé d'adapter un script Perl "pour hier dernier délai". Il est allé à la FNAC (il ne connaissait pas encore les deux temples de la littérature informatique), et a cherché les livres traitant de Perl. Il en a trouvé un avec un lama en couverture, un autre avec un dromadaire, et encore un avec une panthère. Il a donc pris celui avec un lama, puisqu'il semblait s'adresser à des débutants. Il l'a lu dans la soirée, en trois heures, et en faisant tous les exercices. Comme il pensait que cette initiation n'était pas suffisante, il est retourné acheter un autre livre. Je ne sais plus quels étaient ses critères, mais il a choisi Programmation Avancée en Perl. Et le soir même, il s'est plongé dedans. Mais il a laissé tomber au bout d'un quart d'heure, car il s'agissait effectivement de programmation avancée, un peu trop avancée pour son niveau de l'époque.
  • Stéphane aime bien le livre de la Panthère. C'est en effet un livre qui traite de sujets pointus avec le niveau de détail nécessaire. Notamment, c'est la meilleure doc qu'il a trouvée sur le langage XS. La documentation standard, perlxs et perlxstut, n'a pas répondu à ses attentes. Quant à moi, j'émet quelques réserves sur ce livre. Il a été écrit il y a déjà un certain temps (1997), et à ce moment-là, MJD n'avait pas encore écrit ses trois articles sur les dangers des références symboliques. Donc, Sriram Srinivasan présentait les références symboliques sous un jour positif, sans en signaler les dangers. J'ai lu ce livre en mars 2000, après avoir lu les articles de MJD. Sans remettre en cause la compétence de Sriram, je trouve que le texte de 1997 est obsolète.
  • Là où Stéphane et moi sommes d'accord, c'est que la doc électronique ne remplacera jamais la doc papier. La documentation électronique permet, si on sait bien s'en servir, d'obtenir rapidement le renseignement désiré (quoique, lorsque je cherche quelque chose dans le Dromadaire, ça va aussi vite que dans perldoc). Cela permet également de copier et de coller du code. En revanche, on peut feuilleter une documentation papier. Également, il est facile de poser des marque-page dans un livre, et de passer rapidement d'une marque à l'autre. Cela existe dans certains systèmes de documentation électronique, mais c'est beaucoup moins commode. D'autre part, entre ouvrir quelques fenêtres à 72 dpi sur un écran 17 pouces, voire 24 pouces et ouvrir quelques livres et étaler plusieurs feuilles de papier imprimées à 300 dpi sur un mètre carré de bureau, il n'y a pas de comparaison possible.
  • Samuel attend Perl 6 avec une certaine impatience, pour voir comment seront traitées les chaînes de caractères Unicode. Notamment, comment se fera la conversion Kanji -> Hirigana. En effet, les caractères Hirigana sont syllabiques (tout comme le Katakana), tandis que le Kanji est idéographique, le problème étant que deux idéogrammes Kanji totalement différents peuvent être convertis de la même manière en Hirigana.
  • Il existe deux interfaces graphiques pour Perl : Perl/Tk et Perl-Gtk. Pour Stéphane, l'avantage revient sans conteste à Perl-Gtk, qui est d'ailleurs utilisé pour les procédures d'installation de la distribution Mandrake de Linux. Le seul point où Perl/Tk est supérieur à Gtk, c'est le widget texte. Et encore, ce n'est que temporaire. Il est prévu un nouveau widget texte pour Gtk, avec de nombreuses améliorations. Et en plus, il sera possible d'utiliser Unicode.
  • Stéphane trouve la distribution Mandrake intéressante à plusieurs points. Non seulement c'est un exemple d'utilisation de Gtk, mais en plus, c'est du Perl très bien écrit, avec des noms de variable très clairs. D'ailleurs, il y a un certain temps, Stéphane avait posté sur la liste une série de one-liners écrits par Pixel. Ces fonctions figurent à la fin du présent compte-rendu. [ Comme cela, je n'aurai plus besoin de les chercher dans les archives de courrier, je sais où je les ai recopiées. ]
  • Au sujet de la forme à adopter pour les conférences, les participants à YAPC::Europe évoquent la présentation de Template::Toolkit, en la comparant notamment à l'exposé de Stas Bekman. Pour quelqu'un intéressé par le sujet présenté par Stas, l'exposé était intéressant, mais pour quelqu'un qui ne se sentait pas concerné, il était facile de décrocher. En revanche, la présentation de Template::Toolkit comportait une certaine mise en scène. Le premier présentateur faisait un exposé magistral, et de temps à autre, l'autre intervenant l'interrompait avec un "Try me!", et ils enchaînaient sur une démo. En rompant le rythme de la présentation, ils arrivaient à maintenir l'attention de leur auditoire.
  • Stéphane parle d'une implémentation de vi, dans laquelle Perl tient le même rôle que Lisp dans Emacs. Quand je lui parle de Perlmacs et de EPL, de John Tobey, qui permet d'intégrer un interpréteur Perl dans Emacs, Stéphane me répond que l'intégration est boîteuse.
  • Je ne sais plus à quel sujet, quelqu'un a évoqué un groupe allemand de Perl Mongers, Niderheim.pm. Le nom fait penser à ce que l'on trouve dans la mythologie germanique (Nibelungen, etc), mais en fait, il s'agit d'un véritable nom de ville, dans la banlieue de Stuttgart. [ En fait, l'orthographe véritable est Niederrhein, ce qui fait moins penser à la mythologie germanique. ]
  • Quelqu'un (Bernard ?) a parlé d'un collègue, qui écrit parfois 600 lignes de code par jour. Et ce n'est pas du remplissage, c'est du code "trapu", par opposition à ce que produirait un code grinder. Stéphane en a donné une traduction inappropriée. À mon avis, il faut traduire par "pisseur de ligne". La traduction mot-à-mot de grinder est "broyeur" ou dérivé : coffee grinder donne "moulin à café", et meat grinder donne quelque chose comme "hachoir mécanique".

    Internet

  • Bernard cherche à savoir quelle est la jurisprudence au sujet du dépôt légal des noms de domaine. Il a notamment le cas d'un magasin de vêtements de loisirs, qui porte le même nom qu'un organisme de sports. Il se trouve que, pour les marques déposées, on n'a pas le droit de prendre le même nom qu'une société qui travaille dans le même secteur, mais que c'est autorisé s'il s'agit d'un secteur d'activité différent. Et Bernard aimerait savoir ce qu'il en est pour les noms de domaine. Je lui suggère que s'il agissait sans se poser de question, et s'il déposait le même nom de domaine qu'un quasi-concurrent, peut-être ferait-il la une des journaux (presse informatique et journaux à scandale). Et dans ce cas, ce serait la célébrité assurée. "Ah oui, je n'avais pas envisagé le problème sous cet aspect."
  • De l'utilisation d'Internet au boulot, pour des motifs personnels. David (L) a eu vent de l'anecdote suivante : aux États-Unis, un homme a reçu de sa compagne un message de caractère... euh... intime disons. Se sentant flatté par une réflexion de sa compagne, il a envoyé une copie du message à une dizaine de personnes. Celles-ci, à leur tour, ont envoyé ce message à dix autres personnes, et ainsi de suite (pour une fois, une chaîne pyramidale qui a fonctionné !). Au bout d'un temps relativement bref, 100 000 ou 200 000 personnes étaient au courant. Du coup, le gars a été mis à la porte de sa boîte. Philippe (BooK, pas l'autre) dit que ce genre de conversation avec sa copine ne passe pas par le courrier électronique, mais par le téléphone. Je lui réplique qu'elle enregistre toutes leurs conversations sur cassette (et qu'est-ce qu'elle en fait, des cassettes ?).
  • De notre côté de l'Atlantique, le service informatique d'une société avait mis Internet à disposition de tout le personnel, pour une utilisation professionnelle. Une des personnes avait remarqué : "Ah oui, Internet ! Dans l'école de mon fils, ils ont fait un site Internet." Et cette personne, ainsi que quelques collègues, étaient allés consulter le site web de l'école (primaire) en question. Un peu plus tard, ils ont eu une remontrance, car ils avaient accédé à un site susceptible de mettre en danger l'informatique de la société (en effet, les écoles primaires sont infestées de pirates en culottes courtes, qui mettent dans leurs pages web des tas de virus prêts à infecter le PC de quiconque consulte la page web, n'est-ce pas ?).
  • De l'utilisation d'Internet au boulot, pour des motifs en partie professionnels. La messagerie électronique permet de dire bonjour aux collègues, même s'ils sont à l'autre bout du bâtiment. Mais comment le fait-on ? On ouvre Word, on écrit "bonjour, comment ça va ?", on sauvegarde le document Word (20 Ko), on ouvre la messagerie, on crée un nouveau message avec le document Word en pièce jointe (20 Ko), et on envoie le message (20 Ko).
  • Je rapproche cette démarche d'une anecdote, citée dans l'un des derniers numéros de The Perl Journal, où l'auteur de l'article racontait qu'il avait vu une personne utiliser Excel pour faire du traitement de texte, parce que c'était le seul logiciel qu'elle savait utiliser.
  • De l'utilisation d'Internet pour des motifs strictement professionnels. Chaque jour, le siège social d'une banque envoie à toutes ses agences le taux de change de 40 devises, et une dizaine de taux d'intérêt. Dans certains cas les cinquante valeurs peuvent changer, mais en règle générale, seules quelques valeurs changent. Ces données sont envoyées par fax à toutes les agences le matin, et chaque agence diffuse cette information à toutes les personnes concernées. Dans une agence, la diffusion se fait par intranet. Et comment la personne chargée de la diffusion procède-t-elle ? Elle prend le fax, le passe au scanner, récupère le fichier JPEG ou GIF obtenu, et copie ce fichier tel quel dans la page web de l'intranet. Du coup, dans les minutes précédant l'ouverture de l'agence, toutes les personnes de l'agence tentent de charger la même page web, avec le même fichier image de plusieurs centaines de kilo-octets, alors qu'il aurait été si simple de mettre à jour un bête fichier HTML de 3 ou 4 kilo-octets.
  • Slashdot a cité récemment un article racontant que plusieurs sites de commerce électronique se sont fait piéger. Ces sites fonctionnent avec la métaphore du chariot de supermarché, et chaque fois qu'un client sélectionne un article, le site lui renvoie une page HTML dynamique avec le montant total de la commande. Certains acheteurs ont eu l'idée de charger le source HTML dans un éditeur de texte, de modifier les prix et montants (à la baisse, bien sûr), et de renvoyer le tout au serveur de commerce électronique. Et dans certains cas, la commande est passée sans problème ! Pourtant, c'est l'une des premières choses que l'on apprend dans les cours de programmation CGI : il ne faut jamais faire confiance aveuglément aux données reçues.
  • Outre les célèbres moteurs de recherche pour le web, il existe d'autres moteurs de recherche, indexant des sites FTP. Au début, avec ces moteurs de recherche, il était possible de trouver des fichiers /etc/passwd en consultation libre ! Maintenant, ils ont rajouté un filtre pour compenser les bourdes de certains administrateurs systèmes.

    Sujets divers

  • Nous avons évoqué les escroqueries et effractions sur les distributeurs automatiques de billets. Certaines restent d'actualité. Les autres, heureusement, sont un souvenir du passé. Par exemple, dans le temps, la liaison entre un distributeur de billets et l'agence de la banque associée n'était pas toujours protégée. C'est ainsi qu'une personne indélicate pouvait brancher un magnétophone sur le câble, par l'intermédiaire d'une prise ampèremétrique, et envoyer des signaux sur ce câble en "jouant" une cassette. Si la "mélodie" était la bonne, le distributeur s'ouvrait alors sans sollicitation visible, et distribuait les biftons...
  • Une clause légale veut que le compte de la carte bancaire soit débité après que l'utilisateur a pris les billets. Dans le temps, il était possible de forer un trou dans la carte bancaire, et d'y faire passer un fil suffisamment résistant. En synchronisant la main gauche qui prend les billets et la main droite qui tire sur le fil de la carte, il était possible de retirer la carte avant que le montant soit inscrit sur la piste. Maintenant, ce n'est plus possible. Dans les distributeurs honnêtes et respectueux de la loi, la carte bancaire est immobilisée par deux griffes entre le moment où elle est introduite dans la fente et le moment où le débit est inscrit sur la puce. Dans les distributeurs "malpropres", le montant est débité avant l'apparition des billets.
  • Plus brutal : on arrache le distributeur avec un engin de chantier. Seulement, lorsqu'il s'agit de forcer le coffre, un système de sécurité fait qu'une teinture indélébile se répand à l'intérieur du coffre, et que les billets sont inutilisables. J'avais lu une anecdote du genre, qui se passait dans une zone rurale des États-Unis. Les malfaiteurs n'avaient pas utilisé un vrai engin de chantier, mais leur propre pick-up. Au beau milieu de la nuit, ils avaient passé une chaîne autour du DAB, puis ils avaient attaché cette chaîne au pare-choc arrière du pick-up. En tirant sur la chaîne, la fixation du pare-choc a cédé dans un bruit incompatible avec le calme nocturne qui régnait sur la ville. Les malfrats avaient donc pris la fuite, en laissant sur place le distributeur de billets, la chaîne, le pare-choc... et la plaque d'immatriculation ! [ J'ai cherché sur quel site j'avais lu cette anecdote, et hélas je n'ai pas trouvé. Je croyais que c'était les Darwin Awards, mais je n'ai pas trouvé cette anecdote particulière. ]
  • Beaucoup moins drôle : pour dévaliser un distributeur de billets, le moyen le plus simple est de choisir un distributeur dans un supermarché. Inutile de s'attaquer directement au distributeur. Il suffit d'attendre qu'une caissière vienne approvisionner le distributeur, et c'est elle qu'on dévalise. C'est pas un métier facile, le métier de caissière. Une caissière travaille en pointillé, c'est-à-dire qu'elle est active 30 heures par semaine, mais elle passe 70 heures par semaine sur son lieu de travail. Et bien sûr, elle est payée au SMIC sur la base de 30 heures hebdomadaires. Ajoutez à cela le travail répétitif et abrutissant, les clients grincheux... et les attaques à main armée. Je signale qu'il y a aussi le métier d'hôtesse de caisse, qui est nettement mieux. D'accord, on est payé au SMIC sur la base de 30 heures hebdomadaires pour 70 heures passées sur le lieu de travail, d'accord le travail est répétitif et abrutissant, d'accord il y a des clients grincheux et le risque d'une attaque à main armée, mais au moins on a un statut prestigieux, on est hôtesse de caisse.
  • Ou alors, il y a les escroqueries plus centrées sur les cartes. Par exemple, dans certains commerces où le comptoir est si haut que vous ne voyez pas ce que le commerçant fait de votre carte. Il l'introduit dans l'appareil, et vous présente le clavier où vous tapez votre code. Il reprend le clavier, et vous le redonne immédiatement, "car vous avez dû vous tromper". Et vous retapez votre code. Le hic, c'est qu'en fait, il s'agit de deux claviers différents, reliés à deux terminaux monétiques différents. Et le commerçant vous a fait payer deux fois...
  • Variante : lorsque vous payez avec votre carte dans un restaurant, cela se passe ainsi. Vous donnez votre carte. Le serveur l'emporte à la caisse. Quelques secondes, ou quelques minutes plus tard, il revient avec le terminal amovible muni d'un clavier. Vous tapez votre code, sans réellement dissimuler le clavier. Dans certains cas, le serveur attend l'impression de la facturette, et vous rend la carte avec l'exemplaire de la facturette qui vous revient. Dans d'autres cas, il retourne à la caisse, et revient quelque temps plus tard avec la carte et la facturette. Mais entre temps, il est allé au distributeur bancaire voisin, et a effectué un léger retrait sur votre compte...
  • Une société bien connue de l'un des participants cherche à fusionner certaines de ses filiales. La fusion aura lieu dans deux ans, environ, mais on sait déjà que cela va entraîner la disparition du service informatique dans certains sites. Du coup, les postes dans ces sites ont été redistribués, et on ne trouve plus au service informatique que des personnes qui partiront à la retraite dans un délai de deux ans ! Alors que ces personnes ne connaissaient rien à l'informatique jusqu'à présent.
  • Les joyeusetés de la hot-line. Voici quelques échanges typiques entre l'organisme où travaille Nicolas (C), et l'assistance technique Microsoft (je signale qu'ils ont pris ce qui se fait de mieux et de plus cher comme abonnement à l'assistance technique).
  • Bernard, qui a les mêmes logiciels au travail, a un peu les mêmes problèmes. Du coup, lorsqu'il rentre chez lui, pour se délasser, il fait de l'informatique sur sa machine personnelle... qui tourne sous Linux.
  • Parmi les problèmes qu'il rencontre la journée, il y a Visual Basic. Il a eu le cas d'une boucle de 1 à 10, qui a donné comme résultat Ou bien, un programme qui fonctionnait correctement avec
    I=0
    
    et qui ne fonctionnait plus avec
    I = 0
    
    [ VB, Python, RPG, même combat ! ]
  • Un de ces jours, il faudra que nous allions rendre visite à Emmanuel sur son lieu de travail. Ceci pour que le chef d'Emmanuel se rende compte que nous existons réellement. Selon lui, nous sommes un produit de l'imagination d'Emmanuel, rien de plus.
  • Nicolas (C) fait de gros calculs, avec des matrices booléennes 8000 x 8000, et ultérieurement 20000 x 20000. Jusqu'à présent, il utilisait le logiciel Gauss. Le problème, c'est que quel que soit le type de la matrice, chaque élément occupe 10 octets en mémoire. Du luxe pour les booléens ! Puis il a essayé PDL, un module Perl dans lequel il existe un type matrice booléenne. Maintenant, il se tourne du côté de Scilab.
  • N'importe comment, comme le rappelle Philippe (brix), lorsque sa machine super-puissante aura mouliné pendant plusieurs siècles, il obtiendra un résultat, et ce résultat, il est déjà connu. C'est 42, la réponse à l'ultime question sur la vie, l'univers et le reste. [ Je suis content de constater qu'il y en a qui lisent leurs classiques. ]

    Les one-liners de Pixel

    (J'espère que le programme en question est sous licence GPL, ou artistique, ou une quelconque licence open-source. Je ne voudrais pas poser de problème de droits d'auteur au groupe des Perl Mongueurs).
    sub fold_left(&@) {
        my $f = shift;
        local $a = shift;
        foreach $b (@_) { $a = &$f() }
        $a
    }
    
    
    sub __ { $_[0] }
    sub even($) { $_[0] % 2 == 0 }
    sub odd($)  { $_[0] % 2 == 1 }
    sub min { fold_left { $a < $b ? $a : $b } @_ }
    sub max { fold_left { $a > $b ? $a : $b } @_ }
    sub sum { fold_left { $a + $b } @_ }
    sub and_{ fold_left { $a && $b } @_ }
    sub or_ { fold_left { $a || $b } @_ }
    sub sqr { $_[0] * $_[0] }
    sub sign { $_[0] <=> 0 }
    sub product { fold_left { $a * $b } @_ }
    sub first { $_[0] }
    sub second { $_[1] }
    sub top { $_[-1] }
    sub uniq { my %l; @l{@_} = (); keys %l }
    sub to_int { $_[0] =~ /(\d*)/; $1 }
    sub to_float { $_[0] =~ /(\d*(\.\d*)?)/; $1 }
    sub ikeys { my %l = @_; sort { $a <=> $b } keys %l }
    sub add2hash($$)  { my ($a, $b) = @_; while (my ($k, $v) = each %{$b || {}}) { $a->{$k} ||= $v } $a }
    sub add2hash_($$) { my ($a, $b) = @_; while (my ($k, $v) = each %{$b || {}}) { exists $a->{$k} or $a->{$k} = $v } $a }
    sub member { my $e = shift; foreach (@_) { $e eq $_ and return 1 } 0 }
    sub dirname { @_ == 1 or die "usage: dirname <name>\n"; local $_ = shift; s|[^/]*/*\s*$||; s|(.)/*$|$1|; $_ || '.' }
    sub basename { @_ == 1 or die "usage: basename <name>\n"; local $_ = shift; s|/*\s*$||; s|.*/||; $_ }
    sub bool($) { $_[0] ? 1 : 0 }
    sub invbool { my $a = shift; $$a = !$$a; $$a }
    sub listlength { scalar @_ }
    sub bool2text { $_[0] ? "true" : "false" }
    sub bool2yesno { $_[0] ? "yes" : "no" }
    sub text2bool { my $t = lc($_[0]); $t eq "true" || $t eq "yes" ? 1 : 0 }
    sub strcpy { substr($_[0], $_[2] || 0, length $_[1]) = $_[1] }
    sub cat_ { local *F; open F, $_[0] or $_[1] ? die "cat of file $_[0] failed: $!\n" : return; my @l = <F>; wantarray ? @l : join '', @l }
    sub output { my $f = shift; local *F; open F, ">$f" or die "output in file $f failed: $!\n"; print F foreach @_; }
    sub deref { ref $_[0] eq "ARRAY" ? @{$_[0]} : ref $_[0] eq "HASH" ? %{$_[0]} : $_[0] }
    sub linkf { unlink $_[1]; link $_[0], $_[1] }
    sub symlinkf { unlink $_[1]; symlink $_[0], $_[1] }
    sub chop_ { map { my $l = $_; chomp $l; $l } @_ }
    sub divide { my $d = int $_[0] / $_[1]; wantarray ? ($d, $_[0] % $_[1]) : $d }
    sub round { int ($_[0] + 0.5) }
    sub round_up { my ($i, $r) = @_; $i += $r - ($i + $r - 1) % $r - 1; }
    sub round_down { my ($i, $r) = @_; $i -= $i % $r; }
    sub is_empty_array_ref { my $a = shift; !defined $a || @$a == 0 }
    sub is_empty_hash_ref { my $a = shift; !defined $a || keys(%$a) == 0 }
    sub difference2 { my %l; @l{@{$_[1]}} = (); grep { !exists $l{$_} } @{$_[0]} }
    sub intersection { my (%l, @m); @l{@{shift @_}} = (); foreach (@_) { @m = grep { exists $l{$_} } @$_; %l = (); @l{@m} = (); } keys %l }
    
    sub set_new(@) { my %l; @l{@_} = undef; { list => [ @_ ], hash => \%l } }
    sub set_add($@) { my $o = shift; foreach (@_) { exists $o->{hash}{$_} and next; push @{$o->{list}}, $_; $o->{hash}{$_} = undef } }
    
    sub sync { syscall_('sync') }
    sub gettimeofday { my $t = pack "LL"; syscall_('gettimeofday', $t, 0) or die "gettimeofday failed: $!\n"; unpack("LL", $t) }
    sub unix2dos { local $_ = $_[0]; s/\015$//mg; s/$/\015/mg; $_ }
    
    sub remove_spaces { local $_ = shift; s/^ +//; s/ +$//; $_ }
    sub mode { my @l = stat $_[0] or die "unable to get mode of file $_[0]: $!\n"; $l[2] }
    sub psizeof { length pack $_[0] }
    
    

    Retour aux Mongueurs

    Vérification du HTML

    Paris, le 9 July 2010
    Copyright © The Paris Perl Mongers, 1999-2011