[Toulouse-pm] OSCON 2006, Lundi

Michel Rodriguez mrodrigu at ieee.org
Mon Jul 24 21:02:48 PDT 2006


OSCON 2006 - Portland, OR
     Salut les p'tits gars. Donc cette année encore, pas de YAPC::Europe pour
     moi, mais par contre un petit compte-rendu d'OSCON, au cas où quelques
     un d'entre vous ne seraient pas là.

   Dimanche soir
     J'arrive donc dans l'après-midi, sous une chaleur accablante, bonne
     excuse pour gouter les bières locales, légèrement meilleures que les
     Nostro Azzuro ou Moretti auquelles je suis condannées a la maison.

     Je tombe sur quelques têtes connues, MJD avec sa fille, Iris, Nat
     Torkington qui porte un T-shirt Google et un sac MSN qui se battent (la
     femme de MJD éloigne sa fille pour qu'elle ne soit pas contaminée par le
     langage... fleuri de Nat).

     Bon, si je commence comme ça, je crois que dans la version HTML du
     compte rendu je mettrais des div avec des classes ("technique",
     "people", "news", "non_perl", "insultes_gratuites", ...)

     La soirée est assez calme, j'ai encore le double jet-lag (je ne suis
     arrivé que mardi sur la côte est). Donc une paire de bières avec Scott
     Matthews, que je n'avais pas vu depuis une éternité, quelques "ribs"...
     et au lit.

   Lundi Matin
    The 7 principles of better API design - Damian Conway
     J'ai deja vu des bouts de ce cours, mais franchement il n'y avait pas
     grand chose de plus excitant au programme.

     Donc Damian explique que le but c'est de proposer des interfaces
     minimales.

    Principe 1: "Do one thing really well"
     L'API d'un module peut etre tres simple.

     En exemple, il propose IO::All (<http://search.cpan.org/dist/IO-All>) ou
     Perl6::Say (<http://search.cpan.org/dist/Perl6-Say>).

     Il detaille un peu Perl6::Say, qui exporte 1 fonction, "say", un print
     avec un \n a la fin). Curieusement le code de la fonction est un peu
     plus complique que ce que j'aurait pense (pas trop, juste un peu), ce
     qui montre bieng que perl cache bien des choses sous son capot. Au
     passage perl 5.10 aura la fonction "say", et d'autres ("switch"!).

     Sur CPAN, les modules Perl6::* sont souvent de ce type.

     Pour lui, toute séquence d'instructions souvent répétée devrait se
     retrouver dans une fonction, elle-même stockée dans un module.

     Il a écrit un module, Toolkit, qui permet de mettre un paquet de modules
     dans un répertoire, et "use Toolkit" les charge d'un coup
     (<http://search.cpan.org/dist/Toolkit>)

    Principe 2: Design by Coding
     Commencez par écrire le code qui va utiliser le module/fonction que vous
     devez développer, ca vous permet de détecter très tôt la meilleure
     manière d'écrire l'interface. Ecrire des tests est une bonne façon de
     faire ça.

     Exemple: Regexp::Common (<http://search.cpan.org/dist/Regexp-Common>):
     *"Who do you want to write your regular expressions? Abigail!"*.

     Il explique comment il est passé d'une interface où la regexp était
     renvoyée par une fonction, a un simple hash (qui masque une... certaine
     complexitée, qu'il explique). C'est pas mal, ça complète bien la
     présentation d'Abigail que j'avais vu a Londres l'an dernier à la London
     Perl Workshop (c'est masculin ou féminin Worksop?).

     Au passage, une théorie de Larry Wall: certaines tâches ont une
     complexité intrinsèque, le code de toute façon sera compliqué. Par
     contre on peut distribuer cette complexité, et en l'occurence la cacher
     dans les couches basses de l'application. Du coup ça permet d'avoir des
     couches hautes simples, qui peuvent être écrites par des codeurs moins
     expérimentés.

     Puis un conseil: quand on écrit une suite de "if", toujours, TOUJOURS,
     avoir le "else" à la fin. Même si le else ne doit janmais arriver. Dans
     ce cas le faire emettre un message adéquat. Prendre cette habitude
     permet de détecter pas mal de bugs, quand le cas impossible se produit!

     Puis il décrit l'interface de Contextual::Return
     (<http://search.cpan.org/dist/Contextual-Return>) (il note que
     "wantarray" en fait ne dit pas si l'appelant veut un tableau, juste si
     il veut une une liste!).

     Le code de Contextual::Return est assez chiadé par contre, un peu trop
     pour que je puisse l'expliquer ici (la marge de ma fenêtre n'est pas
     assez large).

     A la pause je croise mister Cholet, un couple de fervent Pythoniste et
     Nat qui devient "corporate" (il porte des tongues au lieu de se promener
     pieds-nu comme d'hab).

    Evolve by substraction
     En 2 mots, a partir de l'API initiale, identifier les endroits où
     l'utilisation est un peu bizarre, et réduire la bizarrerie. Souvent ça
     consiste a rajouter des options aux fonctions pour déplacer la
     complexité du code utilisateur vers la fonction de plus bas niveau.

     pause...

     A la reprise, c'est l'heure pour Damian de parler deIO::Prompt
     (<http://search.cpan.org/dist/IO-Prompt>), dont l'interface "Does The
     Right Thing". Comme Contextual::Return il est base sur Want
     (<http://search.cpan.org/dist/Want>), qui est un super "wantarray", mais
     donne beaucoup plus d'infos sur le contexte dans lequel une fonction est
     appelée.

     IO::Prompt exporte une unique fonction, qui fait pleing de choses
     différentes, en fonction des options qui lui sont passées.

    Declarative beats imperative
     Eviter les interfaces où la première chose que l'utilisateur doit faire
     est d'initialiser un paquet de variables. D'abord ça force l'utilsateur
     à lire la doc. Et pis du coup le "vrai" code ne commence qu'assez bas
     dans le code.

     Exemple: "Exporter", avec ses "EXPORT, EXPORT_OK" et autres variables.
     Perl6::Export::Attrs (<http://search.cpan.org/dist/Perl6-Export-Attrs>)
     est plus naturel:

       sub toto :Export( :DEFAULT :ALL) { ... }

     On voit bien que c'est au niveau de la fonction, on déclare l'export,
     pas loin de là. en plus le module offre quelques fonctions que Exporter
     n'offre pas, comme des fonctions qui sont exportées quoique
     l'utilisateur dise (dans le "use"). Il semble que Damian lui même (qui a
     écrit le module) ne sait pas exactement â que point le module est
     magique: aprês une question, il découvre dans le code du module que si
     on fait "use :ALL" toutes les fonctions sont exportées (sauf celles qui
     commencent par "_" je suppose).

     Un autre module qui montre l'intérêt des interfaces déclaratives:
     Getopt::Euclid (<http://search.cpan.org/dist/Getopt-Euclid>) (Euclid est
     un accronyme, mais il le dit tellement vite que je ne saisit pas tout.
     Dans le POD du code on rajoute la description de l'interface de l'outil,
     avec une syntaxe simple... et ça marche.

    Preserve the metadata
     Ne pas obliger l'utilisateur à répéter plusieurs fois les mêmes infos.

     Exemple: Config::Std (<http://search.cpan.org/dist/Config-Std>), qui
     préserve les commentaires dans un fichier de configuration quand il est
     mis à jour. Ca n'est pas très compliqué (pour Damian!), ça suppose juste
     d'avoir un parser qui garde tout, commentaires et ordre des options dans
     le fichier, et de ruser un peu avant de sauver le fichier.

     Oh, et quand on sauve le fichier, pas besoin de redonner le nom du
     fichier, par défault c'est le même. Ca évite souvent de devoir passer le
     nom du fichier partout dans le code où la config peut être mise-à-jour.

     Si on fait ce genre de chose à la maison, le comportement exact dépend
     du type de fichier: on peut vouloir par exemple "comment out" (comment
     ça se dit en français?) les options qu'on a enlevé.

    Leverage the familiar
     Il s'excuse pour l'utilisatin du terme "leverage"...

     Exemple: Log::StdLog (<http://search.cpan.org/dist/Log-StdLog>).
     L'interface est la même que... "print"! Au niveau de log près. Comme ça
     l'utilisateur n'a pas trop de problême a savoir comment utiliser le
     module.

       if( $verbose) {
           local *STDOUT = *STDLOG;
           print debug => "coucou";
           print info  => "rmatique";
           print fatal => "Aaaarrrrrgghhh!";
       }

     Bon, pour les explications techniques sur comment ça marche, j'écoute,
     donc pas de commentaires.

     Il a regardé sur CPAN, les 30+ modules qui font du log. Son commentaire
     est que quand il n'y a qu'un ou 2 modules sur CPAN qui font un truc, en
     général c'est qu'il y a consensus sur la manière de r1soudre le
     problême. Par contre Il admet que Log4Perl est pas mal, mais un peu
     compliqué. Pourquoi avoir un module OO pour du log? Commentaire de mon
     voisin dans la salle: Log4Perl a un "easy" mode qui évite de devoir se
     trimballer un objet partout dans le code. Damian recommende d'y jeter un
     oeil.

     Oops, son micro le lâche. Il va devoir crier, ce qui ne le dérange pas
     trop!

     Citations: *"This is maintenance by complaint"* â quelqu'un qui demande
     un option supplémentaire, je saisis pas laquelle.

    The best code is no code at all
     Le simple fait de faire un "use Module" fait que *"shit happens"*.

     Exemple: Object::Dumper (<http://search.cpan.org/dist/Object-Dumper>)

       use Object::Dumper;
       my $object= MyClass->new( ...);
       print $obj;

     Et ça marche! Ca dumpe le contenu de l'objet, au lieu du classique
     HASH[0x12a8f2] Au passage ça fait aussi un "die" si on essaye de se
     servir de l'objet dans un contexte numérique, sauf bieng sûr si on
     overloade la numérification de la classe.

    Conclusion
     2 grandes forces de perl: Il fait déjà plein de chose pour nous, et il
     ne gène pas (*"it doesn't get in the way"*). On devrait essayer de faire
     la même chose avec notre propre code.

     Un bon tutorial, intéressant parce qu'il allait de principes généraux de
     design d'interface, à des exemples de code assez pointus.

   Lundi apres-midi
    Mastering vim - Damian Conway
     Et oui, c'est la journée Conway. Je me sers à peu près bin de vim, mais
     comme dit Damian "je me sers de vim, il fait ce que je veux, mais je
     sais vaguement qu'il y a plein de trucs super cool qu'il peut faire mais
     que je ne connais pas". Donc tutorial. En plus je tape ce CR avec vim,
     donc ça devrait donner un super texte.

     Son premier conseil: utiliser vim, pas vi. Jusque là j'ai tout bong.

     Je vais pas vous répéter tout ce qu'il dit, juste vous donner les trucs
     sympas (et que je connaissais pas) qu'il donne.

     Toutes les touches du clavier sont des commandes valides. Celles qu'on
     utilise le plus sont à moitié effacées (où complètement dans le cas de
     mon vieux Mac, ce qui me handicape pas mal vu que je connais pas bien le
     clavier).

     Il n'arrête pas de dire "perl" à la place de vim, il menace d'unifier
     les 2 dans le futur.

     Donc une longue liste de trucs que je ne connaissais pas:

     W/B font la même chose que w/b, mais en prenant l'espace comme
         séparateur de mots.

     ^   debut du premier mot de la ligne

     gg  debut du fichier

     g<CTRL-G>
         comme G, mais avec plus de détails.

     set
           set matchpair <:> # < et > sont maintenant des délimiteurs (% va de l'un à l'autre)

     mL (m avec une lettre majuscule)
         même chose que ml, mais global, permet de naviguer entre different
         fichiers.

     :marks
         montre tous les marqueurs

     utiliser les marqueurs avec d'autres commandes
         d'a efface toutes les lignes du curseur au marqueur

     ``  retour au dernier endroit, couplé avec l'utilisation de marqueurs,
         permet de sauter facilement entre 2 régions d'un fichier.

     "   le dernier endroit ou on était la dernière fois qu'on a édité le
         fichier.

     <CTRL-O> <CTRL-I>
         navigue vers l'avant et l'arriêre dans l'historique des sauts entre
         marqueurs

     <n>s
         remplace <n> charactêres par le texte tapé ensuite.

     c<déplacement>
         remplace depuis le curseur jusqu'à la fin du déplacement

     :set backspace=indent,eol,start
         delete efface maintenant tout, sans s'arrêter

     <CTRL-Y>
         insêre le charactère de la même colonne de la ligne au-dessus
         <CTRL-E> pareil avec la ligne au-dessous.

     <CTRL-R>=
         evalue une expression et insêre le résultat

     <CRL-O>
         repasse en mode normal (d'un autre mode) pour une seule commande

     f<char>
         trouve le charactère, intéressant couplé a d par example

     t<char>
         trouve le charactère, et se positionne devant

     set ignorecase
         search devient non case-sensitive

         "set smartcase": case-sensitive seulement si le pattern est tout en
         minuscule.

     \c \C
         case-sensitivity on/off dans un pattern

     :set nohlsearch
         annule le highlighting du search (utile surtout si mappée sur une
         touche)

     10,+33s/<pattern>/<replacement>
         dans le genre:

         le + veut dire 33 lignes après la ligne 10

         . est la ligne courante .+1 est la ligne d'après

         <n>: initialise le range a .,+<n>

         %s: initialise le ragne à 1,$

         on peut utiliser des searches dans le range:
         "/<body>/;<\/body>/s/<I>/<EM>/"

         wahouh!

         Ca marche aussi avec des marqueurs. Damian ne le savait pas. Il
         essaye, ça marche avec ', pas avec `

         Ne pas oublier le g à la fin du s.

         Un c à la fin du pattern demande confirmation de toutes les
         substitutions

         ":s" ou "&" refait la dernière substitution (pratique si on traite
         plusieurs fichiers à la file)

     yap iap
         "yanke" le paragraphe courant (la version avec i ne prends pas les
         espaces avant/après) (je crois, mon Mac a crashé depuis la dernière
         phrase.

     ]p/]P
         paste en respectant le niveau d'indentation. Cool pour bouger du
         code.

     :<range>copy <target>
         devinez ce que ça fait?

     <CTRL-R>n
         insère (en fait tape) le contenu du registre n. <CTRL-R><CTRL-R>n
         fait un vrai insert (les charactères de contrôle sont vraiment
         insérés).

     :set autowrite
         après ça ":next" sauve le fichier courant

     gf  ouvre le fichier dont le nom est sous le curseur

     :read <filename>
         insère le contenu du fichier ":read !<commande shell>"

         marche aussi avec un préfixe: ":Gread <filename>" insère à la fin du
         fichier

         on peut aussi remplacer du contenu ":%!sort" Très utile pour trier
         un paragraphe par exemple (au passage ":sort" est aussi une commande
         de vim, avec diverses options (n numeriquement, u unique, i
         case-insensitive...) "sort!" trie en ordre inverse.

     auto-complétion
         on peut donner des fichiers qu'on ne veut pas auto-completer: ":set
         ???" (j'ai pas saisi)

         Ca marche aussi en mode commande

         En mode perl (ou si on le définit soi-même) <CTRL-X><CTRL-D>
         auto-complète un nom de fonction.

         <CTRL-X><CTRL-N> auto complète un nom (un mot en fait). On peut même
         avoir un fichier avec une liste de noms standards (" set
         complete+=k~/data/my_std_identifiers")

         <CTRL-X><CTRL-L> complète avec une ligne (du fichier) qui commence
         comme la ligne courante.

     configuration
         faire ":options" choisir parmis les milliers d'options possibles,
         puis faire ":mkvimrc" (dans $HOME)

     indentation
         ma config de choix, si je suis bien

           :set shiftround
           :set expandtab
           :set tabstop=4

     substitutions
         Il y a un moyen (par une variable magique) de configurer le moteur
         d'expressions régulières pour qu'il soit plus proche des regexp de
         Perl.

         D'une manière générale, sauts à marqueurs et recherches peuvent
         toujours être utilisés comme modificateurs de commandes: "d/__END__"
         efface tout jusqu'au __END__

     registres
         Les registres sont sauvés entre session, donc on peut s'en
         resservir.

         "A3yy ajoute les 3 liges à la fin du registre a

     undo/redo
         En vim 7 g- et g+ permettent de naviguer entre les branches de
         l'edition. les commandes ":earlier" et ":later" permettent de se
         retrouver dans un état différent (genre ":earlier 10mn").

         On peut éditer normalement (avec les commandes de vim) l'historique
         des commandes ':' en faisant "q:"

     visual mode
         "V" met en mode visuel. Tout déplacement sélectionne le texte,
         ensuite les commandes normales s'appliquent.

         "v" est similaire, mais sélectionne des lignes entières

         "<CTRL-v>" fait pareil, mais sur un block rectangulaire de texte.
         mega-funky comme dit Damian, que je ne sais pas expliquer proprement
         en 3 mots.

         "vip>" selectionne le paragraphe et l'indente

         "vipJ" selectionne le paragraphe et joint les lignes

     abbréviations
           :abbreviate <abbreviation> <texte>

         Par exemple ":abbreviate =i =item" pour ce pod

         A noter qu'on peut par exemple avoir <CTRL-O> pour avoir des
         commandes dans les abbreviations.

         ":iabbrev" marche en mode insert et ":cabbrev" uniquement en mode
         commande (et ":abbrev" dans les 2 modes)

     map
           :imap <abbreviation> <text>

         Les abbréviations sont insérées uniquement si l'abbréviation est
         suivi d'un charactêre non-mot, les map sont insérées dès que les
         charactêres sont tapés.

         On peut programmer les maps pour avoir encore plus de possibilits.

         ":help :map-modes" décrit d'autres modes (xmap pour mode visual,
         omap pour operator-pending mode...)

     Comandes pas très utiles:
           23% envoie à 23% du fichier...

     Il avoue qu'il a couvert à peu prês 10% de ce que peut faire vim.

     Au final un tutorial très dense, avec pleins de trucs. Les notes sont
     très complètes. Ca va me prendre quelques temps pour digérer tout ça.
     Mais déjà j'ai utilisé pas mals de ses trucs en tapant ce CR, donc j'ai
     espoir.

     Désolé pour le franglais dans la liste au dessus, mais ça va assez vite,
     et j'ai pas toujours le temps de traduire tout comme il faut ;--( En
     plus, du coup j'ai sauté presque tout ce que je connaissais déjà, ça m'a
     laissé le temps de respirer un peu. Ah uoi, en plus j'ai sauté tout ce
     qui causait C.

     Bon, fini pour la partie sérieuse d'aujourd'hui, à demain!

     Oh, et désolé pour le manque de g à la fin des mots, je crois que je
     suis en traing de perdre mon assent :--(.

-- 
Michel Rodriguez
IEEE Standards - Electronic Services


More information about the Toulouse-pm mailing list