[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