La doctrine Rails.

David Heinemeier Hansson

La montée en puissance phénoménale de Ruby on Rails est due en grande partie à sa technologie novatrice et à son timing. Mais les avantages technologiques s’érodent avec le temps et un bon timing ne permet pas de maintenir les mouvements sur le long terme. Une explication plus large de la manière dont Rails a continué à rester non seulement pertinent, mais également à renforcer son impact et sa communauté est nécessaire. Je propose que le catalyseur permanent ait été et reste sa doctrine controversée.

Cette doctrine a évolué au cours de la dernière décennie, mais la plupart de ses plus puissants piliers en sont également les fondateurs. Je ne prétends pas à l’originalité fondamentale de ces idées. L’accomplissement principal de Rails a été de réunir et de former une tribu forte autour d’un large éventail de pensées hérétiques sur la nature de la programmation et des programmeurs.

Après ce préambule, voici les neuf piliers les plus importants de la doctrine Rails, tels que je les perçois :

  1. Optimisez pour le bonheur des programmeurs
  2. Convention plutôt que Configuration
  3. Le menu est omakase
  4. Pas de paradigme unique
  5. Exalter du beau code
  6. Fournir des couteaux affûtés
  7. Donnez de la valeur aux systèmes intégrés
  8. Progrès plutôt que stabilité
  9. Monter une grande tente

Optimisez pour le bonheur des programmeurs

Il n’y aurait pas de Rails sans Ruby, il est donc normal que le premier pilier doctrinal soit tiré de la motivation fondamentale qui a motivé la création de Ruby.

L’hérésie originelle de Ruby consistait en effet à placer le bonheur du programmeur sur un piédestal. Au-dessus de nombreuses autres préoccupations concurrentes et valables qui ont conduit aux langages de programmation et les écosystèmes avant lui.

Là où Python pouvait se vanter d’être “une et de préférence une seule façon de faire quelque chose”, Ruby adorait l’expression et la subtilité. Alors que Java défendait avec force les programmeurs d’eux même, Ruby a inclus une corde suspendue dans le kit de bienvenue. Là où Smalltalk a percé une pureté de transmission de messages, Ruby a accumulé des mots-clés et des constructions avec un appétit de glouton.

Ruby était différent parce qu’il valorisait différentes choses. Et la plupart de ces choses étaient au service de cette aspiration au bonheur des programmeurs. Une quête qui a mis en contradiction avec non seulement la plupart des autres environnements de programmation, mais également avec la perception générale de ce qu’était un programmeur et de la façon dont il était censé agir.

Ruby a dû non seulement reconnaître mais aussi accommoder et élever les sentiments des programmeurs. Qu’ils soient d’insuffisance, de fantaisie ou de joie. Matz a sauté des obstacles de mise en œuvre d’une complexité incroyable pour faire en sorte que la machine semble sourire et flatter son co-conspirateur humain. Ruby est plein d’illusions d’optique où ce qui semble simple, clair et beau à nos yeux est en fait un désordre acrobatique de fils sous le capot. Ces choix n’étaient pas gratuits (demandez à l’équipe de JRuby d’essayer de désosser cette boîte à musique magique ! ), c’est précisément pourquoi ils sont si louables.

C’est mon attachement à une autre vision de la programmation et des programmeurs qui a scellé mon histoire d’amour avec Ruby. Ce n’était pas seulement la facilité d’utilisation, ce n’était pas seulement l’esthétique des blocs, ce n’était pas une simple réalisation technique. C’était une vision. Une contre-culture. Une place pour les inadaptés n’appartenant pas au moule de programmation professionnel existant et a l’état d’esprit associé.

Dans le passé, j’ai décrit cette découverte de Ruby comme un gant magique qui me correspond parfaitement au cerveau. Mieux que je n’aurais jamais imaginé qu’un gant puisse aller. Mais c’était même plus que ça. C’est cet événement qui a marqué ma transition personnelle, passant de “faire de la programmation parce que j’avais besoin de programmes” à “faire de la programmation parce que j’en tombais amoureux, en tant que mode d’exercice et d’expression intellectuelle”. Elle recherchait une source de flux et d’être capable de l’allumer à volonté. Pour tous ceux qui connaissent le travail de Csikszentmihalyi, il est difficile de surestimer l’impact de ce phénomène.

Je n’exagère pas en disant que Ruby m’a transformée et a jeté les bases du travail de ma vie. La révélation était si profonde. Il m’a imposé un appel à faire un travail de missionnaire au service de la création de Matz. Pour aider à diffuser cette création profonde et ses avantages.

Maintenant, je peux imaginer que la plupart d’entre vous secouent la tête avec incrédulité. Je ne vous en veux pas. Si quelqu’un m’avait décrit l’expérience précédente alors que je vivais encore sous le paradigme “la programmation n’est qu’un outil”, j’aurais également secoué la tête. Et puis j’aurais probablement ri de l’usage excessif du langage religieux. Mais pour que cela soit vrai, il faut aussi que ce soit réaliste, même si c’est désagréable pour certains ou même pour la plupart.

Quoi qu’il en soit, qu’est-ce que cela signifie pour Rails et comment ce principe continue-t-il de guider son évolution ? Pour répondre à cette question, j’estime qu’il est instructif d’observer un autre principe souvent utilisé pour décrire Ruby à ses débuts : le début de la moindre surprise. Ruby devrait se comporter comme vous le souhaitez. Ceci est facilement décrit par rapport à Python :

$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit

$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit

Ruby accepte la sortie et quitte pour refléter le désir évident du programmeur de quitter sa console interactive. Python, d’autre part, indique au programmeur, de manière pédiatrique, comment faire correctement ce qui est demandé, même s’il sait évidemment ce que cela signifie (car il affiche le message d’erreur). C’est un exemple assez clair, bien que petit, de PoLS.

La raison pour laquelle PoLS est tombé en disgrâce pour la communauté Ruby est son approche subjective. Surprenant pour qui ? Eh bien, pour Matz. Et les gens qui sont aussi surpris de la même manière que lui. Au fur et à mesure que la communauté Ruby grandissait, et que le nombre de personnes qui étaient surprises par des choses différentes de celles de Matz augmentait, cela devenait une source de perte de vitesse sur les listes de diffusion. Le principe s’est donc estompé à l’arrière-plan, de peur d’inviter davantage de débats qui ne mènent nulle part, que la personne X ait été surprise par le comportement Y ou non.

Alors, encore une fois, qu’est-ce que cela a à voir avec Rails ? Eh bien, Rails a été conçu avec un principe similaire au principe de moins de surprise (pour Matz). Le principe du plus grand sourire (pour DHH), qui décrit bien ses qualités : des API conçues avec une grande attention pour tout ce qui me ferait sourire de plus en plus. Quand je l’écris de cette façon, cela semble presque narcissique, et j’ai même du mal à argumenter contre cette première impression.

Mais créer quelque chose comme Ruby ou Rails est, du moins au départ, une tâche profondément narcissique. Les deux projets sont issus de l’esprit d’un créateur unique. Mais peut-être que je projette ici mes propres motivations dans celles de Matz, alors permettez-moi de limiter la portée de ma proclamation à ce que je sais : j’ai créé Rails pour moi. Pour me faire sourire, tout d’abord. Son utilité était subordonnée à de nombreux degrés à sa capacité à me faire profiter davantage de ma vie. Enrichir mon travail quotidien chargé d’exigences et de demandes de systèmes d’information Web.

Comme Matz, j’ai parfois travaillé dur pour mettre en œuvre mon principe. L’Inflector, par exemple, est une classe qui contient suffisamment de modèles et d’irrégularités de la langue anglaise pour affecter une classe Person à une table People, d’une analyse à une autre et simplement d’un commentaire à un commentaire. Ce comportement est maintenant accepté comme un élément incontestable de Rails, mais les flammes de la controverse ont été déchaînées avec une grande intensité dans les premiers jours, alors que nous rejoignions encore la doctrine et son importance.

Un autre exemple nécessitant moins d’effort de mise en œuvre, mais causant presque la même consternation: Array#second à #fifth (et #forty_two pour le troll). Ces pseudonymes ont été très choquants pour certaines personnes qui ont déploré le fait que tant d’ornements soient utilisés pour quelque chose qui pourrait aussi être écrit comme Array#[1], Array#[2] (et Array#[41]).

Les deux solutions me font sourire aujourd’hui. Je suis heureux d’écrire people.third comme un cas de test dans la console. Non, ce n’est pas logique. Ce n’est pas efficace. Mais cela me fait sourire et suit les principes pour enrichir ma vie, et me permet de justifier mon engagement continu avec Rails après 12 ans.

Contrairement à l’optimisation des performances, par exemple, il est difficile de mesurer l’optimisation du bonheur. Cela le rendait presque non scientifique dans son essence, ce qui le rend moins important, voire totalement frustrant. On enseigne aux programmeurs à discuter et à travailler avec des problèmes mesurables, dans lesquels une conclusion claire peut être tirée, où A est catégoriquement meilleur que B.

Mais si la recherche du bonheur est difficile à mesurer au niveau micro, il est beaucoup plus clair d’observer au niveau macro. La communauté Ruby on Rails est pleine de gens qui sont ici justement à cause de cette recherche. Ils se vantent d’une vie professionnelle meilleure et plus épanouie. C’est dans cet ensemble d’émotions que la victoire est claire.

Nous concluons donc : l’optimisation du bonheur est peut-être la clé la plus fondatrice de Ruby on Rails. Et cela continuera ainsi.

Convention plutôt que Configuration

L’un des premiers slogans de Rails était : “Vous n’êtes pas un flocon de neige magnifique et unique”. La devise dit qu’en abandonnant l’individualité, il est possible d’éviter de résoudre des problèmes triviaux et d’avancer plus rapidement dans les domaines qui sont vraiment importants.

Qui se soucie du format dans lequel vos clés primaires sont décrites dans la base de données ? Est-ce vraiment important si c’est “id”, “postId”, “posts_id” ou “pid” ? Cette solution mérite-t-elle une discussion constante ? Non.

Une partie de la mission de Rails consiste à faire tourner sa machette à l’épaisseur croissante dans la jungle épaisse et sans cesse croissante de décisions récurrentes auxquelles sont confrontés les développeurs qui créent des systèmes d’information pour le Web. Il y a des milliers de décisions de ce genre qui ne devraient être prises qu’une seule fois, et si quelqu’un d’autre peut le faire pour vous, alors, beaucoup mieux.

Le transfert de la configuration à la convention nous libère non seulement de la discussion, mais offre également un champ luxuriant permettant de développer des abstractions plus profondes. Si nous pouvons compter sur un mapping de la classe Person à la table des personnes, nous pouvons utiliser cette même inflexion pour mapper une association déclarée comme has_many :people à la recherche d’une classe Person. Le pouvoir des bonnes conventions est qu’elles rapportent des dividendes dans un large éventail d’utilisations.

Mais en plus des gains de productivité pour les experts, les conventions réduisent également les obstacles à l’entrée pour les débutants. Dans Rails, il existe de nombreuses conventions qu’un débutant n’a même pas besoin de connaître, mais dont ils peuvent bénéficier simplement en les ignorant. Il est possible de créer de bonnes applications sans savoir pourquoi tout est comme cela et fonctionne.

Ce n’est pas possible si votre framework est simplement un manuel volumineux et que votre nouvelle application est un morceau de papier vierge. Il faut d’énormes efforts pour déterminer par où et comment commencer. La moitié du combat consiste à trouver un fil à tirer.

Ce sera la même chose quand vous comprenez comment toutes les pièces vont ensemble. Quand il y a une prochaine étape évidente pour chaque changement, nous pouvons parcourir les nombreuses parties d’une application qui sont identiques ou très similaires à toutes les autres applications qui l’ont précédée. Une place pour chaque chose et chaque chose à sa place. Les contraintes libèrent même les esprits les plus capables.

Comme pour tout, cependant, le pouvoir de la convention n’est pas sans danger. Lorsque Rails rend les choses tellement simples, il est facile de penser que tous les aspects d’une application peuvent être formés par des modèles prédécoupés. Mais la plupart des applications qui méritent d’être construites comportent des éléments uniques. Ce ne peut être que 5% ou 1%, mais c’est là.

La partie difficile est de savoir quand sortir de la convention. Quand les détails divergents sont-ils suffisamment graves pour justifier une excursion ? Je soutiens que la plupart des impulsions pour être un flocon de neige magnifique et unique sont mal prises en compte, et que le coût de la sortie des rails est sous-estimé, mais qu’un nombre suffisant d’entre elles ne sera pas nécessaire pour que vous les examiniez toutes attentivement.

The menu is omakase

Comment savez-vous ce que vous devriez commander dans un restaurant quand vous ne savez pas ce qui est bon ? Eh bien, si vous laissez le chef choisir pour vous, il peut probablement vous suggérer un bon repas, même avant de savoir ce qui est “bon”. Ceci est Omakase. Une façon de bien manger qui ne nécessite ni d’être un expert en cuisine, ni de posséder une chance inavouable à choisir dans le noir.

Pour la programmation, les avantages de cette pratique, permettant aux autres d’assembler votre stack, sont similaires à ceux que nous tirons de Convention plutôt que Configuration, mais à un niveau supérieur. CoC s’occupe de l’utilisation d’un framework, tandis que Omakase traite de quels frameworks à utiliser et de la manière dont ils collaborent les uns avec les autres.

Ceci est en contradiction avec la tradition de programmation vénérée qui consiste à présenter les outils disponibles comme des choix individuels et à donner aux programmeurs le privilège (et le fardeau !) de décider.

Vous avez sûrement entendu parler, et vous avez probablement hoché la tête, “utilisez le meilleur outil pour le travail”. Cela semble assez élémentaire pour être sans débat, mais être capable de choisir le “meilleur outil” dépend d’une base qui permet de déterminer le “meilleur” avec confiance. C’est beaucoup plus difficile qu’il n’y parait.

C’est un problème similaire à celui de dîner dans un restaurant. Et comme choisir chaque partie dans un repas de huit plats, choisir chaque bibliothèque ou chaque framework n’est pas un travail fait en isolement. L’objectif dans les deux cas est de considérer toute la soirée ou le système.

C’est pourquoi avec Rails nous avons décidé de réduire un bien, le privilège individuel d’un programmeur à choisir chaque outil dans sa boîte, pour un plus grand : une meilleure boîte à outils pour tous. Les dividendes sont légion :

  1. Les chiffres parlent d’eux-mêmes : lorsque la plupart des gens utilisent Rails de la même manière, nous partageons notre expérience. Ce terrain d’entente facilite beaucoup l’enseignement et l’entre aide. Cela jette les bases d’un débat sur l’approche. Nous avons tous regardé la même émission hier soir à 19 heures, donc nous pouvons en parler le lendemain. Cela favorise un sens plus fort de la communauté.
  2. Les gens perfectionnent la même boîte à outils de base : en tant que framework complet, Rails comporte de nombreuses pièces mobiles et leur collaboration est aussi importante que ce qu’elles font isolément. Une grande partie de la douleur dans le logiciel ne provient pas des composants individuels, mais de leurs interactions. Lorsque nous travaillons tous à réduire la douleur partagée par les composants configurés et qui échouent de la même manière, nous éprouvons tous moins de douleur.
  3. Les substitutions sont toujours possibles, mais pas obligatoires : bien que Rails soit une stack omakase, il vous permet néanmoins de remplacer certains frameworks ou bibliothèques par des alternatives. Cela ne vous oblige tout simplement pas. Cela signifie que vous pouvez retarder ces décisions jusqu’à ce que vous ayez développé une palette claire et personnelle qui peut ainsi préférer la différence occasionnelle.

Parce que même les programmeurs les plus érudits et les plus expérimentés qui viennent à Rails et y restent ne sont probablement pas opposés à toutes les questions du menu (s’ils l’étaient, ils n’auraient probablement pas pris Rails). Ils choisissent donc leurs substitutions avec diligence, puis profitent du reste de la stack organisée et partagée avec tous les autres.

Pas de paradigme unique

C’est un fort attrait émotionnel que de choisir une seule idée centrale et de la suivre jusqu’à la conclusion logique en tant que fondement de votre architecture. Une telle discipline est pure, alors pourquoi les programmeurs sont-ils naturellement attirés par cette lumière brillante ?

Rails n’est pas comme ça. Ce n’est pas une simple, ni parfaite coupe de tissu. C’est une courtepointe. Un composite de beaucoup d’idées différentes, et même de paradigmes. Beaucoup qui seraient généralement en conflit, si on les contrastait seul et un par un. Mais ce n’est pas ce que nous essayons de faire. Ce n’est pas un championnat d’idées supérieures où un seul gagnant doit être déclaré.

Prenez les gabarits avec lesquels nous avons créé les vues dans notre gâteau Rails-MVC. Par défaut, toutes les aides qui nous permettent d’extraire du code à partir de ces gabarits constituent simplement un excellent ensemble de méthodes. C’est un seul espace de noms. Oh, surprise, horreur, c’est comme une soupe PHP !

Mais je soutiens que PHP avait raison lorsqu’il s’agissait de présenter des fonctions individuelles qui nécessitaient rarement une interaction, comme c’est le cas avec beaucoup d’abstraction dans les gabarits de vue. Et à cette fin, l’espace de nom unique, le grand pot de méthodes, n’est pas seulement un choix raisonnable, mais un excellent choix.

Cela ne signifie pas que nous ne souhaitons pas parfois atteindre quelque chose de plus orienté objet lors de la création de vues. Le concept de présentateurs, dans lequel nous encapsulons de nombreuses méthodes interdépendantes et les données qu’il contient, peut parfois être l’antidote idéal contre une panoplie de méthodes perturbées par des dépendances. Mais il s’est avéré qu’il s’agissait généralement d’une chose plutôt rare.

En comparaison, nous considérons généralement le modèle dans nos couches de gâteau MVC comme le principal bastion de la qualité orientée objet. Trouver le bon nom pour les objets, augmenter la cohérence et réduire le couplage, voilà le plaisir de la modélisation de domaine. C’est une couche très différente de la vue, nous adoptons donc une approche différente.

Mais même ici, nous ne souscrivons pas à un dogme à paradigme unique. Les concerns Rails, la spécialisation des mixins de Ruby, sont souvent utilisées pour donner aux modèles individuels une très grande surface. Cela correspond bien au modèle Active Record en donnant aux méthodes concernées un accès direct aux données et au stockage avec lesquels elles interagissent.

Le fondement même du framework Active Record choque certains puristes. Nous combinons la logique nécessaire pour l’interface avec la base de données directement avec le domaine métier et la logique. Un tel amalgame de frontières ! Oui, car cela s’est avéré être un moyen pratique d’envelopper une application Web qui dispose presque toujours d’une connexion à la base de données pour conserver l’état du modèle de domaine.

Être aussi flexible sur le plan idéologique est ce qui permet à Rails de traiter un aussi large éventail de problème. La plupart des paradigmes individuels fonctionnent très bien dans une certaine partie du problème, mais deviennent maladroits ou rigides lorsqu’ils sont appliqués au-delà de leur sphère naturelle de confort. En appliquant de nombreux paradigmes qui se chevauchent, nous couvrons les flancs et gardons l’arrière. Le cadre final est bien plus fort et plus performant qu’un paradigme individuel ne l’aurait permis.

Maintenant, le coût de cette relation polygame avec les nombreux paradigmes de la programmation est une surcharge conceptuelle. Il ne suffit pas de connaître la programmation orientée objet pour passer du bon temps avec Rails. Il est préférable d’avoir bien profité d’expériences procédurales et fonctionnelles.

Ceci s’applique également aux nombreux sous-langages de Rails. Nous n’essayons pas de vous protéger du fait de devoir apprendre, par exemple, JavaScript pour la vue ou SQL pour les requêtes parfois compliquées. Du moins ne pas atteindre les sommets des possibilités.

Pour alléger un peu le fardeau de l’apprentissage, il suffit simplement de faciliter les débuts, de créer quelque chose de vraiment précieux avant de comprendre tous les aspects du framework. Pour cette raison, nous sommes pressés de montrer le “Hello World” typique. Votre table est déjà préparée et un apéritif est servi.

L’idée est qu’en donnant rapidement quelque chose de vraiment précieux, nous encouragerons les praticiens de Rails à passer rapidement au niveau supérieur. Acceptez leur parcours d’apprentissage comme une joie et non comme un obstacle.

Exalter du beau code

Nous écrivons du code non seulement pour être compris par l’ordinateur ou par d’autres programmeurs, mais également pour profiter de la chaleur de la beauté. Un code esthétique est une valeur en soi et doit être poursuivi avec vigueur. Cela ne veut pas dire que le beau code l’emporte toujours sur les autres préoccupations, mais il devrait avoir entièrement sa place à la table des priorités.

Alors qu’est-ce que le code beau ? En Ruby, il se situe souvent à l’intersection des idiomes natifs de Ruby et de la puissance d’un langage personnalisé du domaine. C’est une ligne floue, mais cela vaut la peine d’essayer de danser.

Voici un exemple simple tiré d’Active Record :

class Project < ApplicationRecord
  belongs_to :account
  has_many :participants, class_name: 'Person'
  validates_presence_of :name
end

Cela ressemble à un DSL, mais c’est vraiment juste une définition de classe avec trois appels de méthode de classe prenant des symboles et des options. Il n’y a rien d’extraordinaire ici. Mais c’est sûr, c’est joli. C’est sûr, c’est simple. Cela donne une quantité énorme de puissance et de souplesse à ces quelques déclarations.

Une partie de la beauté provient de ces appels qui respectent les principes précédents, tels que Convention plutôt que Configuration. Lorsque nous appelons belongs_to :account, nous supposons que la clé étrangère s’appelle account_id et qu’elle se situe dans la table des projets. Lorsque nous devons désigner le class_name de Person pour le rôle d’association de participants, nous avons simplement besoin de cette définition de nom de classe. Nous en tirerons à nouveau les clés étrangères et d’autres points de configuration.

Voici un autre exemple tiré du système de migration de bases de données :

class CreateAccounts < ActiveRecord::Migration
  def change
    create_table :accounts do |t|
      t.integer :queenbee_id
      t.timestamps
    end
  end
end

C’est l’essence même du pouvoir du framework. Le programmeur déclare une classe conformément à certaines conventions, comme une sous-classe ActiveRecord::Migration qui implémente #change, et le framework peut effectuer tout le travail et la plomberie qui en découle, et connaître la méthode à appeler.

Cela laisse au programmeur très peu de code à écrire. Dans le cas de migrations, non seulement cela permettra un appel à rails db:migrate pour mettre à niveau la base de données afin d’ajouter cette nouvelle table, mais aussi pour inverser le processus de suppression de cette table avec un autre appel. C’est très différent d’un programmeur qui réalise tout cela et assemble le workflow à partir de bibliothèques qui s’appellent eux-mêmes.

Parfois, un code magnifique est plus subtil. Il s’agit moins de créer quelque chose d’aussi court ou puissant que possible, mais de donner le rythme au flux de déclaration.

Ces deux déclarations font la même chose :

if people.include? person
...
if person.in? people

Mais le flux et le focus sont légèrement différents. Dans la première déclaration, l’accent est mis sur la collection. C’est notre sujet. Dans la deuxième déclaration, le sujet est clairement la personne. Il n’y a pas beaucoup de différence de longueur entre les deux déclarations, mais je dirai que la seconde est beaucoup plus belle et risque de me faire sourire si elle est utilisée dans un endroit où la condition concerne la personne.

Fournir des couteaux affûtés

Ruby comprend de nombreux couteaux affûtés dans son tiroir de fonctions. Pas par accident, mais par conception. Le plus célèbre est le monkey patch : le pouvoir de changer les classes et méthodes existantes.

Ce pouvoir a souvent été considéré comme simplement trop exagéré par de simples programmeurs mortels. Les gens de milieux plus restrictifs avaient l’habitude d’imaginer toutes sortes de calamités qui condamneraient Ruby en raison de l’immense confiance que la langue accordait à ses locuteurs dotés de cette fonctionnalité.

Si vous pouvez changer quelque chose, qu’est-ce qui vous empêche de réécrire String#capitalize pour que “quelque chose d’audacieux”.capitalize renvoie “Quelque chose d’Audacieux” plutôt que “Quelque chose d’audacieux” ? Cela pourrait fonctionner dans votre application locale, mais ensuite casser toutes sortes de codes auxiliaires qui dépendent de l’implémentation d’origine.

Rien, c’est la réponse. Ruby n’a rien de programmé pour vous empêcher d’utiliser ses couteaux affûtés pour couper les liens avec raison. Nous faisons respecter ces bons sens par convention, par coups de pouce et par éducation. Pas en bannissant les couteaux affûtés de la cuisine et en insistant pour que tout le monde utilise des cuillères pour trancher les tomates.

Parce que le monkey patching a le pouvoir d’exercer des émerveillements tels que 2.days.ago (qui renvoie une date de deux jours en arrière par rapport au courant). Maintenant, vous pourriez bien penser que ce n’est pas une bonne affaire. Vous préférerez perdre 2.days.ago si cela signifie empêcher les programmeurs d’écraser String#capitalize. Si telle est votre position, Ruby n’est probablement pas pour vous.

Pourtant, il serait difficile - même pour les personnes qui renonceraient à une telle liberté pour des raisons de sécurité - de faire valoir que le pouvoir de changer les classes et méthodes fondamentales a condamné Ruby en tant que langage. Au contraire, le langage a prospéré parce qu’il offrait une perspective différente et radicale du rôle du programmeur : on pouvait leur faire confiance avec des couteaux bien affûtés.

Et non seulement leur faire confiance, mais en ayant appris à les utiliser au mieux de leurs capacités. Nous pourrions élever l’ensemble de la profession en supposant que la plupart des programmeurs voudraient devenir de meilleurs programmeurs, capables de manier des couteaux affûtés sans se couper les doigts. C’est une idée incroyablement ambitieuse, qui va à l’encontre de l’intuition des programmeurs sur les autres programmeurs.

Parce qu’il s’agit toujours d’autres programmeurs lorsque la valeur des couteaux affûtés est contestée. Je n’ai pas encore entendu un seul programmeur lever la main et dire “Je ne peux pas me faire confiance avec ce pouvoir, retirez-le-moi, je vous en prie !”. C’est toujours “je pense que d’autres programmeurs abuseraient de cela”. Ce type de paternalisme ne m’a jamais attiré.

Cela nous amène à Rails. Les couteaux fournis par le framework ne sont pas aussi affûtés que ceux proposés avec le langage, mais certains sont toujours prêts à couper. Nous ne nous excuserons pas d’offrir de tels outils dans le kit. En fait, nous devrions célébrer d’avoir assez confiance dans les aspirations de nos collègues programmeurs pour oser leur faire confiance.

De nombreuses fonctionnalités de Rails ont été qualifiés de “trop de liberté” au fil du temps. Cependant, un exemple actuellement en vogue est la fonctionnalité concerns. Il s’agit d’une fine couche de sucre syntaxique entourant la fonctionnalité intégrée des modules de Ruby et elle est conçue pour permettre à une classe unique d’encapsuler de multiples préoccupations liées, mais désignées de manière indépendante (soit concerns en anglais, d’où le nom).

Le problème est que ces concerns fournissent aux programmeurs enclins à gonfler leurs objets de nouveaux tiroirs à encombrer. Et c’est vrai. Les concerns peuvent en effet être utilisées ainsi.

Mais la grande erreur serait de penser qu’en ne fournissant pas une fonctionnalité comme celle-ci, qui, utilisée même par des mains moyennement douées, permet une séparation partielle éloquente des concepts, nous mettions les programmeurs sur la voie du bonheur architectural. Si vous ne pouvez pas vous fier au fait de garder l’évier de la cuisine à l’abri de vos soucis, vous ne risquez pas de vous retrouver avec un brillant lustre d’élégance.

Les programmeurs qui n’ont pas appris à manier des couteaux tranchants ne vont pas faire des meringues maintenant. Mot impératif ici : maintenant. Je crois que chaque programmeur a la possibilité, sinon le droit, de devenir un programmeur Ruby et Rails pleinement capable. Et par capable, je veux dire suffisamment compétent pour savoir quand et comment, en fonction de leur contexte, il doit utiliser les différents outils, parfois dangereux, dans les tiroirs.

Cela n’abdique pas la responsabilité de les y aider. Le langage et le framework doivent être des tuteurs patients, prêts à aider et à guider quiconque vers l’expertise. Tout en reconnaissant que le seul moyen sûr d’y parvenir passe par le pays des erreurs : des outils mal utilisés, un peu de sang, de la sueur et peut-être même quelques larmes. Il n’y a tout simplement pas d’autre moyen.

Ruby on Rails est un environnement pour les chefs et ceux qui souhaitent le devenir. Vous pouvez commencer à faire la vaisselle, mais vous pouvez travailler à diriger la cuisine. Ne laissez personne vous dire que vous ne pouvez pas faire confiance au meilleur outil du commerce dans le cadre de cette aventure.

Donnez de la valeur aux systèmes intégrés

Rails peut être utilisé dans de nombreux contextes, mais son premier amour est la fabrication de systèmes intégrés : monolithes majestueux ! Un système complet qui répond à tout un problème. Cela signifie que Rails est concerné par tout, du JavaScript en front nécessaire pour effectuer des mises à jour en direct à la migration de la base de données d’une version à une autre en production.

C’est un domaine très vaste, comme nous en avons discuté, mais pas plus large que d’être réaliste à comprendre pour une seule personne. Rails cherche spécifiquement à outiller les individus généralistes pour réaliser ces systèmes complets. Son objectif n’est pas de séparer les spécialistes dans de petites niches, mais de faire appel à des équipes entières pour créer quelque chose de durable.

C’est l’accent mis sur l’autonomisation de la personne qui pointe vers le système intégré. C’est dans le système intégré que nous pouvons éliminer de nombreuses abstractions inutiles, réduire le double emploi entre les couches (comme les modèles sur le serveur et le client) et, surtout, éviter de distribuer notre système avant même de le devoir absolument.

Une grande partie de la complication dans le développement de systèmes provient de l’introduction de nouvelles limites entre les éléments qui limitent la façon de passer des appels entre A et B. Les appels de méthode entre objets sont beaucoup plus simples que les appels de procédure distants entre micro services. Il existe un tout nouveau monde de blessures dans les états d’échec, les problèmes de latence et les calendriers de mise à jour de dépendance qui attendent ceux qui s’aventurent dans l’antre de la distribution.

Parfois, cette distribution est simplement nécessaire. Si vous voulez créer une API pour votre application Web que d’autres personnes peuvent appeler via HTTP, il vous suffira alors de la maîtriser et de résoudre bon nombre de ces problèmes (bien que le traitement des demandes entrantes plutôt que leur envoi en sortie soit beaucoup plus facile, votre downtime est une erreur chez quelqu’un d’autre !). Mais c’est au moins une quantité limitée de dommages infligés à votre propre expérience de développement personnel.

Les systèmes sont désintégrés prématurément et fractionnés en services, ou pire encore, en micro services. Cette conduite part souvent de l’idée fausse selon laquelle si vous voulez une application Internet moderne, vous devez simplement construire plusieurs fois le système : une fois côté serveur, une fois côté client JavaScript MVC, une fois pour chacun des applications mobiles, etc. Ce n’est pas une loi de la nature, c’est inutile.

Il est tout à fait possible de partager de gros morceaux de l’application entière sur plusieurs applications et accès. Utiliser les mêmes contrôleurs et vues pour le Web “desktop” que pour les applications mobiles natives. Centrer autant que possible autour de ce monolithe glorieux et majestueux : le système intégré.

Tout cela sans perdre grand-chose, si ce n’est rien en termes de rapidité, d’expérience utilisateur ou d’autres attributs qui entraînent faussement les développeurs vers une distribution prématurée.

C’est ce que nous recherchons avant tout : nous avons toute la puissance des applications distribuées et accordées individuellement avec la facilité d’utilisation et la compréhension d’un système intégré unique.

Progrès plutôt que stabilité

Lorsque les systèmes existent depuis plus d’une décennie, à l’instar de Rails, leur tendance naturelle est l’ossification. Il y a un million de raisons pour lesquelles chaque changement peut être un problème pour quelqu’un, quelque part, qui dépend du comportement passé. Et les justes raisons qui sont aussi pour l’individu.

Mais si nous écoutons trop les voix du conservatisme, nous ne verrons jamais ce qui se passe de l’autre côté. Nous devons oser occasionnellement casser et changer la façon dont les choses évoluent et se développent. C’est cette évolution qui maintiendra Rails en état de survie et de prospérité pour la (les ?) décennie à venir.

Tout cela est facile à comprendre en théorie, mais beaucoup plus difficile à avaler en pratique. En particulier, lorsque votre application rompt avec une modification incompatible avec une version antérieure de Rails. C’est à ces moments-là que nous devons garder à l’esprit cette valeur, que nous chérissons le progrès plutôt que la stabilité, pour nous donner la force de déboguer, de comprendre et de progresser avec le temps.

Ce n’est pas une licence pour infliger des blessures inutiles ou excessives, bon gré mal gré. La Grande Migration de Rails 2.x à 3 persiste encore dans le tissu cicatriciel de beaucoup de personnes présentes. C’était difficile. Un bouleversement grave qui a longtemps laissé beaucoup de personnes sur le territoire 2.x, dont certaines ont été plus que convaincantes. Mais, dans le grand schéma des choses, cela en valait encore la peine.

Ce sont de bonnes affaires que nous devons continuer à faire. Est-ce que Rails sera mieux dans cinq ans pour les changements que nous apportons aujourd’hui ? Est-il préférable que Rails adopte une autre problématique, comme la mise en file d’attente ou WebSockets, dans les années à venir ? Si oui, alors allons-y et faisons le travail.

Ce travail n’est pas seulement quelque chose qui doit se faire dans Rails, mais aussi dans la communauté Ruby au sens large. Rails devrait être à la frontière pour aider Ruby à progresser en poussant ses membres à adopter plus rapidement les versions ultérieures.

Nous avons très bien réussi jusqu’ici. Depuis mes débuts, nous sommes passés à Ruby 1.6, 1.8, 1.9, 2.0, 2.1, 2.2 et maintenant à la version 2.3. De nombreux changements majeurs sont intervenus en cours de route, mais Rails était là pour faire revenir Ruby et aider tout le monde à accéder plus rapidement au programme. C’est en partie le privilège et l’obligation que Rails sert de vulgarisateur majeur de Ruby.

Cela vaut également pour les outils auxiliaires de la chaîne. Bundler était autrefois une idée controversée, mais l’insistance de Rails selon laquelle il s’agit de la pierre angulaire d’un avenir partagé, est aujourd’hui considérée comme acquise. Il en va de même pour des éléments tels que le pipeline d’assets et Spring, le processus de commande persistant. Tous les trois ont traversé, ou vivent encore, des douleurs de croissance, mais l’évidence de leur valeur à long terme nous a aidés à y faire face.

Au bout du compte, le progrès concerne principalement les personnes et leur volonté de faire avancer le changement. C’est pourquoi il n’y a pas de places à vie dans des groupes tels que Rails Core ou Rails Committers. Les deux groupes sont destinés à ceux qui travaillent activement à faire progresser le framework. Pour certains, leur intérêt dans de tels progrès ne durera peut-être que quelques années et nous leur serons toujours reconnaissants pour leurs services, et pour d’autres, cela peut durer des décennies.

C’est pourquoi il est si important pour nous de continuer à accueillir et à encourager les nouveaux membres de la communauté. Nous avons besoin de sang neuf et d’idées neuves pour faire de meilleurs progrès.

Montez une grande tente

Avec autant d’idées controversées à son actif, Rails pourrait rapidement devenir un groupe insulaire d’ermites idéologiques, si nous demandions à tout le monde de faire preuve d’une déférence totale à l’égard de tous les principes, tout le temps. Donc nous ne le faisons pas !

Nous avons besoin d’un désaccord. Nous avons besoin de dialectes. Nous avons besoin de diversité de pensées et de personnes. C’est dans ce creuset d’idées que nous aurons les meilleures choses à partager. Beaucoup de gens ajoutent leurs petits grains de sel, dans le code ou les arguments réfléchis.

Ainsi, alors que cette doctrine décrit une forme idéalisée, la réalité quotidienne est beaucoup plus nuancée (et intéressante). Rails est capable de supporter une si grande communauté sous une tente, car il y a très peu de tests décisifs, voire aucun.

Le succès continu de RSpec, un DSL pour les tests avec lequel j’ai souvent exprimé un profond mécontentement, en est la preuve parfaite. Je peux dire jusqu’à ce que je sois au beau milieu de la raison pour laquelle je ne pense pas que c’est la voie à suivre et qu’elle peut encore s’épanouir et prospérer. Ce point est le plus important !

Il en va de même pour l’avènement de Rails en tant qu’API. Bien que mon objectif et mon dévouement personnels soient axés sur le système intégré qui inclut la vue, il est indéniable que Rails peut faire de bonnes choses avec les personnes qui souhaitent distribuer leurs clients et leurs serveurs dès le départ. Nous devrions accepter cela dans la mesure où cela peut coexister en tant que mission secondaire, et je pense que cela est certainement possible.

Avoir une grande tente ne veut pas dire être tout pour tous. Cela signifie simplement que vous accueillez toutes les personnes à votre fête et leur permettez d’apporter leurs propres boissons. Nous ne devons rien perdre de notre âme ni de nos valeurs en offrant aux autres de nous rejoindre, et nous pourrions bien apprendre à mélanger une nouvelle boisson délicieuse ou deux.

Cela ne vient pas gratuitement. Il faut travailler pour être accueillant. Surtout si votre objectif n’est pas simplement d’attirer davantage de personnes qui ressemblent à celles qui font déjà partie de la communauté. Réduire les barrières à l’entrée est un travail que nous devrions toujours prendre au sérieux.

Vous ne savez jamais si la prochaine personne qui commence à corriger une faute d’orthographe dans la documentation ne finira pas par mettre en oeuvre la prochaine grande fonctionnalité. Mais vous avez une chance de le savoir si vous souriez et dites merci pour toute petite contribution qui stimule la motivation.