Pour ma propre archives : Les conventions d’organisation des fichiers et des classes pour les gem Ruby
Catégorie : Développement informatique
-
Je veux changer ça, et ça, et ça
Je pense que je ne suis pas le seul à imaginer régulièrement comment créer un nouveau langage ou modifier les existants à ma convenance. Sans aller jusque là, en croisant ce qui se fait dans les différents langages, on trouve toujours des point intéressants qu’on aimerait voir copiés.
Voilà donc quelques unes de mes frustrations, parce que les exprimer permet de s’en débarrasser un peu et de se concentrer sur l’important : ce qu’on fait avec le langage.
Persistance du code en PHP
Chaque requête web recharge entièrement l’applicatif PHP. APC apporte une béquille indispensable mais ça reste au niveau de la béquille. Toute l’initialisation est à refaire à chaque fois. Ça fonctionne, mais j’aimerai vraiment un mode de PHP ou un framework web PHP qui permette de commencer directement au traitement des requêtes sans avoir à tout refaire de zéro.
Accesseurs en PHP
Toujours côté PHP j’attends depuis bien longtemps l’apparition d’accesseurs transparents pour les attributs des objets. Ruby, Python et Javascript ont chacun leur façon de faire. Là il ne s’agit pas de repiquer une syntaxe au langage voisin mais bien de combler un manque.
Sérieusement, je n’en peux plus de ces getX() et setX(). C’est encore plus pénible à l’utilisation qu’à la création.Espaces de noms
Fut un temps je râlais beaucoup contre PHP mais ce dernier une bonne partie du retard qu’il avait. Mieux : Arrivé en dernier il s’est permis de parfois faire les choses plus intelligemment.
Dites, pourquoi n’ai-je pas d’espaces de nom en Javascript ?
Les « use » de PHP me manquent aussi en Ruby. Ils présentent une solution élégante et pour donner des noms courts en local à des classes qui viennent d’autres espaces de noms, mais ils permettent aussi les alias pour changer facilement une implémentation par une autre sans impacter le code.
Pendant qu’on y est, pourquoi pas d’auto-chargement en Ruby ? Si je charge X::Y::Z, j’aimerai bien que le langage se charge tout seul d’aller chercher le fichier X/Y/Z.rb. Ça fonctionne dans quasiment tous les autres langages mais Ruby continue de faire du spaghetti d’inclusion manuelle de fichiers.
Blocs et fermetures lexicales
Les blocs sont *la* fonctionnalité qui me fait utiliser Ruby. On peut certes faire beaucoup de choses similaires avec des fonctions anonymes en Javascript ou en PHP mais c’est juste moins élégant (et ça compte beaucoup pour se sentir à l’aise).
Par contre, sérieusement, la réception des paramètres dans les blocs est vraiment peu lisible. Le choix de la barre verticale comme délimiteur est juste illisible.
Le pire arrive avec les fermetures lexicales. Ruby laisse bien trop facilement utiliser par erreur une variable venant de la portée parente. La syntaxe pour forcer une variable comme locale ajoute encore plus au côté non lisible. |x, y=3; z| ? sérieusement ?
À côté de ça PHP et Python proposent des variables en lecture seule, ce qui limite la casse. PHP impose même de déclarer explicitement les variables à importer de la portée parente au lieu de déclarer les variables locales. Difficile à imaginer en monde Ruby mais assez confortable au final.
Et vous ? qu’est-ce que vous changeriez en premier ?
-
La lame de fond nodejs
En ce moment côté startup et innovateurs, les développeurs javascript ont le vent en poupe. Pour autant, je ne crois pas que Javascript côté serveur soit le rouleau compresseur qu’on veut nous faire croire.
La syntaxe du langage est honnête, mais a largement autant de points négatifs que de points positifs par rapport à l’existant ailleurs.
Si je résume, on me dit que Javascript a
- Une grosse base de développeurs à cause de son utilisation dans les pages web
- Un runtime existant sur quasiment toutes les machines
- La possibilité d’avoir un seul langage côté client et côté serveur
- Un système de prototype
- Un système d’event loop, api asynchrones et callbacks sur nodejs
La base d’utilisateur est un facteur très important, mais sur ceux ci une frange très mineure peut se réclamer d’avoir une bonne connaissance de Javascript. Le niveau moyen est même presque pire que sur PHP. Si on se contente de ceux qui font plus de quelques lignes et qui pourraient passer côté serveur, la base utilisateur n’est plus si fantastique que cela. PHP ou Java en ont probablement autant si ce n’est plus.
On trouve de quoi exécuter Javascript même sous Windows, mais au final on va installer une machine virtuelle dédiée. Encore une fois, si on parle de côté serveur, Linux et autres BSD sont une bien meilleure cible et là Python ou Ruby sont par défaut, PHP est déployable facilement, Java est presque partout. Je n’ai jamais entendu dire que l’un des trois premiers souffrait d’un frein à cause de la nécessité d’installation sur telle ou telle machine.
La possibilité d’avoir un seul langage n’est pas à négliger, mais au final coder du Javascript pour une page web dans le navigateur n’est pas comme coder du Javascript pour nodejs : Les API, les performances, les besoins, tout ça est différent. Même sans ça, les partages de code entre client et serveurs resteront anecdotique, Java en a fait l’expérience il y a longtemps. Reste la syntaxe qui est la même, et évite un nouvel apprentissage, mais c’est assez faible. L’expertise dans un langage est principalement liée à l’API et à ses implications, la syntaxe de base s’apprend rapidement.
Le système de prototype est effectivement une des spécificités de Javascript par rapport aux langages courants. Ceci dit c’est un point incompris par quasiment tous les développeurs au point que tous essayent de recréer artificiellement un système de classe au dessus du système de prototype. Le résultat est d’ailleurs un peu bancal. En théorie le système de prototype ça peut être génial. Dans la réalité, sauf pour une petite minorité, c’est un gros point noir. Difficile de considérer ça comme un avantage.
Il reste un point, particulier : Tout l’environnement Javascript côté serveur s’est construit autour d’un système asynchrone bourré de callback. S’il est facile d’y faire de la programmation spaghetti, c’est aussi une grande force et la plus grande spécificité du langage.
Avoir un système d’évent loop avec des accès asynchrones c’est réalisable sur les autres langages, mais ça prend du temps. Il faut refaire tout un jeu de bibliothèques. Les quelques essais actuels sont limités, complexes à mettre en oeuvre, et surtout n’ont pas eu le coup de projecteur qui a lancé nodejs.
Et c’est un peu ça l’idée : Rien n’empêche Ruby, Python ou Java de créer une bibliothèque équivalente à nodejs. S’il y a une vraie valeur ajoutée, alors ça se fera. À ce moment là, à part le coup de projecteur, Javascript n’aura plus de quoi prétendre être en avance. Ça restera un bon langage, avec une excellente machine virtuelle, qui méritera probablement d’être côté serveur, mais pas plus que les autres. Je ne vois pas ce qui justifiera la lame de fond que certains imaginent.
-
Accesseurs
Je déteste avoir à programmer ou utiliser des accesseurs. Voilà, c’est dit.
Sérieusement, qui a eu l’idée de faire des méthodes getX() et setX() ? Dans le meilleur des cas c’est pénible a écrire et difficile à lire.
Qu’on ne me parle pas d’encapsulation, ces méthodes artificielles sont tout sauf un besoin d’encapsulation. C’est même exactement le contraire de l’encapsulation : C’est parce que je n’ai pas à savoir si un attribut est en accès direct ou non que je n’ai pas à utiliser d’accesseurs.
Il n’est pas besoin d’impacter la manière dont on appelle les attributs d’un objet pour différencier l’interface publique et les données internes. De nombreux langages on trouvé une manière élégante de gérer les accesseurs au niveau du langage au lieu de faire faire des pirouettes à l’utilisateur. Un des gros avantages c’est qu’on ne commence à définir des méthodes d’accesseur que quand on en a vraiment l’utilité, pas « partout, au cas où pour plus tard ».
Donc, quand il s’agit de migrer un attribut autrefois en accès direct, en Javascript :
A = { get b() { return this._b; }, set b(val) { return this._b = val;} }; // ou A.__defineGetter__("b", function() { return this._b; }; A.__defineSetter__("b", function(val) { return this._b = val; };
en Ruby :
class A def b @b end def b=(val) @b = val end end
en Python :
class X(object): def getb(self): return self._b def setb(self, val): self._b = val b = property(getb, setb) # ou mieux : class X(object): @property def b(self): return self._b @b.setter def b(self, val): self._b = val
Sérieusement, c’est moins de complexité pour démarrer du code (pas besoin de développer des accesseurs passe-plat au cas où on en aurait besoin plus tard, on peut s’en occuper uniquement quand le besoin arrive), et c’est plus de clarté pour tout ce qui utilise notre code (et là le gain est immense même si ça semble juste quelques caractères). Je n’imagine pas de m’en passer dans les langages où ça existe.
Si vous utilisez des getter et setter passes-plat, c’est soit votre code qui est mauvais, soit votre langage qui est bridé (soit que vous utilisez consciemment un langage bas niveau). Dans les deux premiers cas il y a quelque chose à repenser.
Bien entendu PHP reste à la traine, sous prétexte de simplicité (allez comprendre).
-
Évolution de PHP – accesseurs
Il y a matière à se réjouir : Le développement et l’évolution du langage PHP a repris. Nous avons eu les fonctions anonymes, les espaces de nom, et quelques nouveautés bienvenues, souvent attendues de trèèèèès longue date.
Bref, ça bouge, bien. Nous avons cependant encore deux courants très opposés au niveau du langage : L’un qui souhaite le garder simple et « comme il est », avec souvent un historique quick’n dirty, et qui au final freine quasiment toutes les évolutions. L’autre qui souhaite le voir profondément changé, et reprendre les bonnes idées des autres langages, au risque de trop vouloir copier ces autres langages.
Si je devais caricaturer je dirai qu’une majorité des développeurs de PHP (surtout les historiques) sont ceux qui freinent, et qu’une majorité des utilisateurs actifs de PHP sont ceux qui poussent. Si ça bouge depuis PHP 5.3, c’est que l’excès du « on ne touche rien » a provoqué un trop grand ras-le-bol, et les développeurs de PHP ont été forcés de mettre de l’eau dans leur vin.
Malheureusement les deux courants existent toujours et rien n’a été tranché. On le voit très bien sur la RFC concernant les accesseurs : Une bonne partie des « contre » sont ceux que je qualifie de « développeurs historiques du langage », et une partie des « pour » sont ceux que je qualifie de « utilisateurs actifs dans le langage ».
Il est plus que temps de décider où l’on va, sinon nous allons continuer à avoir un Frankenstein.
-
Élaboratoire sur la documentation des performances web
Il y a quelques temps j’ai relâché publiquement mon travail initial sur un livre en français dédié à la performance des sites web. Relâcher en public ne suffit pas et pour voir apparaitre une documentation utile qui devient pas obsolète il faut créer une vraie dynamique de mise à jour et de completion. Le besoin d’une vraie référence en français (et même en anglais) est là, et il n’y a pas besoin que d’experts pour y arriver.
Sudweb arrive et j’y animerai un élaboratoire. Je vous propose d’y travailler ensemble à la documentation des pratiques et des problématiques de performance. L’objectif est de réamorcer une dynamique qui permette d’arriver à un contenu utile et mis à jour.
Pour que la session soit efficace il faut préparer un peu :
En préalable il faut réussir à pointer un maximum le contenu manquant ou à réécrire. Si vous avez peu de temps, choisissez un sujet qui vous semble pertinent. Ce peut être une problématique croisée récemment, un sujet abordé dans un billet de blog ou un point technique plus général. Ce peut être un sujet bateau, une problématique très pointue ou un point de détail (même très en détail, n’ayez pas peur). Peu importe en fait, si le contenu est manquant ou à mettre à jour : Créez un ticket sur github pour le signaler.
C’est là que vous pouvez aider, et c’est ça qui peut nous permettre d’avoir un contenu de référence utile et pertinent au sujet de la performance web. Je répète : *Vous* pouvez aider. Oui, *vous* aussi, même si vous ne venez pas (mais je vous encourage à venir).
Tout le monde peut participer et y investir le temps qu’il peut, même 10 minutes, quel que soit le niveau technique. Si vous ne savez pas par quoi commencer regarder vos dix lectures précédentes côté performance web et vérifiez que tout ce qui vous semble utile est présent dans le contenu actuel. Mieux : À partir de maintenant faites un tour à chaque fois que vous lisez quelque chose sur la performance pour vérifier si c’est déjà dans le livre.
En avril nous ferons un second travail de qualification et de regroupement pour tenter de constituer des groupes de tâches avec des objectifs précis et réalisables pour Sudweb.
Merci de votre aide et n’hésitez pas à relayer ce billet.
-
Paliers de responsive design
Et si nous dépassions les positions de principe ?
Pour faire une mise en page web « responsive », des gens biens me déconseillent de me servir des tailles des différents appareils pour imaginer les paliers sur lesquels modifier l’agencement. L’idée est de travailler sur le contenu et d’imaginer ce qui est le plus pertinent pour le contenu, indépendamment des appareils sur le marché, qui vont de toutes façons évoluer.
Oui, ok, en théorie. Maintenant il est temps de travailler la pratique.
Je peux faire une optimisation ou un nouvel agencement à chaque fois que l’espace disponible me permet d’apporter un peu de valeur ajoutée. Je finirai avec une multitude de paliers différents. Certains me demanderont du temps, peut être beaucoup, alors qu’ils ne représentent quasiment aucun visiteur. Autant dire que j’aurai perdu du temps.
À l’inverse, je peux prévoir uniquement quelques paliers principaux et laisser les marges ou tailles s’adapter parce que mon contenu le permet. Ce sera correct et lisible partout mais peut être que tel ou tel type d’appareil représente beaucoup de visiteurs et qu’un palier ou qu’une optimisation supplémentaire aurait apporté un retour sur investissement significatif.
Au final je vais devoir faire des choix de palier non seulement en fonction de mon contenu, de l’ergonomie visée et du temps disponible, mais aussi en fonction des visiteurs et de leur matériel. C’est une classique question de retour sur investissement, de ratio entre la valeur ajoutée et l’investissement nécessaire : Je veux que ce soit correct partout, mais je veux concenter mes efforts supplémentaires là où c’est le plus utile et visible.
Même sans toucher au nombre de paliers, l’ergonomie et les contenus ne dictent pas toujours un palier très précis. Je peux finalement viser un peu plus tôt ou un peu plus tard sans que ça ne change grand chose, j’apporterai juste une solution légèrement différente. Tel ou tel appareil risque de se retrouver proche d’un palier et avoir connaissance de cette proximité me permet un quick-win au niveau de la valeur ajoutée qu’il serait dommage de rater.
Bien évidemment c’est une réflexion qui dépend en partie des appareils, de la répartition des utilisateurs et des prévisions tels que nous en disposons aujourd’hui. Cela peut changer, et cela changera. Si je prends correctement en compte le design et l’ergonomie alors le rendu restera correct. Peut être pas autant optimisé qu’au départ, mais pas moins bon que si je ne prends pas du tout en compte les appareils et utilisateurs au départ.
-
Quelques outils pour simplifier github
Pour mes propres archives, et pour ceux qui ne connaissent pas encore, github met à disposition deux outils pour simplifier les interactions :
Le premier c’est github pour mac, une interface graphique simpliste mais efficace pour gérer les dépôts, commit et branches. Ça ne fait pas le café mais ça fait la base utile pour ceux qui ont une utilisation naive. Le bonus ce sont les notifications d’activité qui passent alors dans le système d’alerte intégré d’OS X.
Le second c’est hub, un remplacement de la commande git pour les adeptes de la ligne de commande. On ajoute simplement quelques simplifications de commandes. Rien d’indispensable, mais de quoi éviter de réfléchir quand on bosse avec github : utiliser les couples utilisateur/projet dans la ligne de commande, créer une branche à partir d’une pull request, initier un fork, lancer une pull request, etc.
Côté alertes pour les différents commits d’un projet, il y a aussi Committed (pour Mac OS X là aussi)
Naholyr a aussi un petit script pour gérer les pull request, en surcouche à hub.
-
Joyeux effets javascript – file upload et Twitter bootstrap
Les gens compétents se déchaînent et on voit maintenant apparaitre des choses que nous aurions à peine imaginé du temps où j’étais intégrateur web. Nous étions capable de créer tel ou tel composant, mais en créant tout de zéro ou presque. Désormais des bibliothèques pré-existantes donnent un coup d’accélérateur gigantesque.
Aujourd’hui je suis retombé sur le téléchargement de fichiers, et les exemples du bootstrap proposé sont plus que convaincants. Le menu à gauche pour gérer le positionnement dans la page est lui aussi une très bonne idée bien implémentée.
Je ne peux cependant pas m’empêcher de me poser la question de la charge en terme de performance quand on utilise plusieurs composants. Rien que baser tout ça sur jquery risque de faire mal côté mobile.
-
Les rayures de la webperf
Jeudi confession : Quand je vois un orateur français faire une intervention publique au sujet de la performance web, j’ai encore parfois l’impression qu’il usurpe ma place. Oh, je ne le pense pas, mais il y a parfois le petit pincement, un peu comme si le sujet était mon bébé.
Je vous propose un petit jeu : Si vous intervenez sur un sujet performances des sites web, mettez un vêtement à rayures (horizontales les rayures), publiez une photo dans le groupe flickr dédié et faites un lien dans les commentaires ci-dessous avec le contexte. Conférences, ateliers, formations, même avant-ventes si ça vous amuse : tout le monde peut jouer.
Si vous croisez des intervenants qui ne jouent pas, tentez de les convaincre. Ceux qui ont d’anciennes photo qui correspondent peuvent jouer aussi.