Overblog Suivre ce blog
Editer l'article Administration Créer mon blog
30 août 2013 5 30 /08 /août /2013 13:21

Bonjour,

Je prends la plume aujourd'hui pour vous présenter un nouveau projet sur lequel j'œuvre depuis environ un mois : Rossignol, un agrégateur de flux RSS pour environnements de bureau.

 

screen_rossignol.png

 

L'envie de tester un peu les bibliothèques d'interface utilisateur graphique en D m'a pris. D'après les forums, l'une des plus abouties est DWT, un binding de SWT, la bibliothèque du projet Eclipse, l'environnement de développement intégré populaire dans le monde Java. Point n'est question de Java ici, puisque DWT est 100% native, mais le code à écrire sera très Java-esque, et pas vraiment idiomatique.

Mais revenons à nos moutons, ou devrais-je dire, à nos rossignols. Quand j'ai vu avec quelle relative facilité j'arrivais à faire une interface graphique fonctionnelle avec DWT, il m'a pris l'envie de lancer un petit projet autour de ça. Rossignol était né.

Je n'ai jamais trouvé chaussure à mon pied en matière d'agrégateur RSS. Du coup, pourquoi ne pas faire le mien ? Après tout, ça ne doit pas être très compliqué…

 

XML, mon amour

 

Autant le dire tout de suite, le module std.xml de la bibliothèque standard de D est mauvais. Sa documentation le reconnait comme obsolète et voué à être remplacé par quelque chose de mieux. Dès lors, il me semblait totalement absurde de l'utiliser. J'avais donc le choix entre utiliser un binding vers une bibliothèque C/C++ existante et réécrire un parser moi-même. C'est cette dernière option que j'ai choisie.

Contrairement à C et C++, D a une manière bien à lui de gérer les chaines de caractères. Ce sont des tableaux de caractères Unicode immuables. En outre, les tableaux de D ont des propriétés intéressantes que n'ont pas les tableaux C :

  • Ils connaissent leur taille
  • Ils sont découpables en sous-tableaux (slices), un peu comme les listes en Python. Un slice est simplement une paire de pointeurs qui fonctionne comme une vue d'un ensemble plus grand.

Ces propriétés permettent de tirer quelques conclusions :

  • Dans un programme multithread, on n'a pas besoin de synchroniser les accès aux chaines de caractères. Elles peuvent être partagées librement entre les threads, puisqu'elles sont immuables.
  • Pour prendre une sous-chaine à partir d'une chaine plus grande, on ne copie pas celle-ci, on la slice (ce qui revient à copier deux pointeurs). Dans le cadre d'un parseur événementiel (à la SAX), cela augure d'excellentes performances par rapport au C (où il faut forcément faire une copie pour pouvoir rajouter le 0 terminal).

Ce sont ces deux conclusions m'ont incité à tenter d'écrire moi-même le parsing XML de Rossignol. XML n'étant pas un format atrocement compliqué, j'avais un prototype fonctionnel en moins d'une semaine. La prise en charge d'Unicode directement par le langage, la programmation par contrats et les tests unitaires intégrés sont les trois fonctionnalités de D que j'ai le plus appréciées durant cet exercice. Le langage permet de spécifier des contraintes à vérifier avant et après chaque brique de la chaine logicielle. Avec ça, dès que l'on casse quelque chose, on reçoit une exception AssertError au démarrage nous indiquant quelle contrainte a été violée, ce qui fait gagner un temps fou en mise au point.

 

DWT, la bibliothèque graphique

 

Venons en maintenant à DWT. Comme je l'ai déjà dit, c'est en quelque sorte un portage en D de SWT. On écrit du D comme si on écrivait du Java. Les langages étant très proches du point de vue syntaxique, on peut presque copier/coller les snippets de code de SWT et les recompiler tels quels. Ça rend la documentation très simple, c'est un bon point.

En revanche, le style Java n'est pas le meilleur qui soit pour D : devoir instancier une classe pour gérer un événement alors qu'on pourrait utiliser un delegate n'est pas optimal. En plus, cela nécessite d'utiliser le ramasse-miettes là où on pourrait s'en passer (allocation sur la pile pour les classes à sémantique de valeur comme Point ou Size, par exemple) : On met inutilement la pression sur le GC.

A contrario, certaines fonctionnalités de D sont les bienvenues. Là où  SWT prohibe l'héritage en Java de ses widgets, le alias this de D permet d'ajouter des fonctionnalités à une classe sans en dériver.

J'ai opté pour une interface épurée. Seules les fonctionnalités essentielles doivent être mises en avant. Nous autres geeks avons souvent le défaut de vouloir rajouter le plus de fonctionnalités possibles dans l'interface. Je crois que c'est un défaut. Il n'y a qu'à comparer les interfaces des navigateurs Web entre les années 1990 et les années 2010. Alors que le nombre de fonctionnalités a explosé, les interfaces se sont faites de moins en moins chargées et vont directement à l'essentiel. C'est cette ligne directrice que je me suis fixée pour ce projet. Je me refuse par exemple à rajouter une quatrième colonne dans le panneau de droite alors que j'aimerai bien pouvoir classer les articles par catégorie. Je vais devoir réfléchir à une autre manière de fournir cette fonctionnalité (les suggestions sont les bienvenues).

 

Le bazar des flux

 

Connaissez-vous cette petite BD xkcd sur les standards ? Et bien elle pourrait coller à merveille pour le monde merveilleux de la syndication de contenu Web. Si l'histoire de RSS vous intéresse, je vous suggère de lire sa page Wikipédia, mais pour faire les chose simplement, voici l'état des lieux des formats les plus utilisés aujourd'hui :

  • L'évolution historique du premier format RSS de Netscape est RSS 1.1 (RSS veut ici dire Rich Site Summary). Il utilise des éléments de l'espace de nom RDF et pallie souvent son manque de fonctionnalités avec des extensions, par exemple des tags du Dublin Core.
  • Le format RSS 2.0 (RSS voulant dire ici Really Simple Syndication) est le format le plus utilisé de nos jours. Il est incompatible avec le premier et fournit les fonctionnalités les plus courantes absentes de l'autre. Comme son nom l'indique, c'est un format simple.
  • Atom est un standard IETF (RFC 4287) dont la vocation est de fournir un format très détaillé et le plus exhaustif en fonctionnalités possible. Par exemple, un même article peut avoir plusieurs auteurs et/ou contributeurs, il sait gérer de multiples types de lien (internes et externes) ainsi que de multiples langues.


Autour de ces trois familles de flux gravitent des formats hybrides (comme des flux RSS 2.0 utilisant des dates issues du Dublin Core) ainsi que des microformats dédiés à une application particulière. Bref c'est le bazar ! :)

 

Conclusion

 

Voilà pour cette petite introduction à mon nouveau projet. Il y a encore beaucoup à dire mais je ne voudrais pas saturer mon auditoire. Je consacrerai un prochain billet à expliquer comment est géré le parallélisme dans Rossignol. Le langage D propose plusieurs approches du threading (de plus ou moins haut niveau) et je vous parlerai une prochaine fois des solutions que j'ai retenues.

Partager cet article

Repost 0
Published by Olivier - dans Projets personnels
commenter cet article

commentaires

Présentation

Recherche

Liens