• Contenu
  • Bas de page
logo ouidoulogo ouidoulogo ouidoulogo ouidou
  • Qui sommes-nous ?
  • Offres
    • 💻 Applications métier
    • 🤝 Collaboration des équipes
    • 🛡️ Sécurisation et optimisation du système d’information
    • 🔗 Transformation numérique
  • Expertises
    • 🖥️ Développement logiciel
    • ♾️ DevSecOps
    • ⚙️ Intégration de logiciels et négoce de licences
      • Atlassian : Jira, Confluence, Bitbucket…
      • Plateforme monday.com
      • GitLab
      • SonarQube
    • 📚​ Logiciel de CRM et de gestion
    • 🎨 UX/UI design
    • 🌐 Accessibilité Numérique
    • 🗂️​ Démarches simplifiées
    • 📝 Formations Atlassian
  • Références
  • Carrières
    • 🧐 Pourquoi rejoindre Ouidou ?
    • ✍🏻 Nous rejoindre
    • 👨‍💻 Rencontrer nos collaborateurs
    • 🚀 Grandir chez Ouidou
  • RSE
  • Ressources
    • 🗞️ Actualités
    • 🔍 Articles techniques
    • 📖 Livres blancs
    • 🎙️ Interviews Clients
Nous contacter
✕
Optionnal Chaining et Démineur
Optionnal Chaining et Démineur
29 mai 2020
Pilotez vos tests Elixir avec des scénarios
Pilotez vos tests Elixir avec des scénarios
11 juin 2020
Ressources > Articles techniques > Vous reprendrez bien un morceau ?

Vous reprendrez bien un morceau ?

Article écrit par François Vantomme

Le langage Ruby foisonne de méthodes diverses et variées pour manipuler des chaînes de caractères, des nombres, des collections, et bien d’autres. Prenons le cas des collections par exemple. Il en existe de plusieurs sortes : Array, Hash ou encore Set pour ne citer que les plus utilisées. Et qu’ont-elles toutes en commun ? Ce sont des Enumerable, c’est-à-dire qu’elles incluent ce module et ainsi partagent quantité de méthodes fort utiles lorsque l’on manipule des collections.

Parmi ces méthodes, certaines semblent extrêmement spécialisées, parfois obscures, à tel point qu’on peut avoir du mal à comprendre dans quelle situation elles peuvent s’avérer utiles. Jusqu’au jour où cette situation se présente, et là, c’est la révélation !

Cela m’est arrivé récemment alors que je travaillais à l’amélioration d’un outil développé en interne chez Ouidou Nord. Son but est de nous faciliter la tâche lors de la conversion de nos articles de blog — tel que celui que vous lisez en ce moment — rédigés en Markdown, vers leur mise en page finale en HTML.

Cet outil se comporte comme se comporteraient de petits utilitaires Unix spécialisés que l’on chaîne pour aboutir au résultat final.

               ╭────────────────── Pipeline ─────────────────╮                │                                             │ ╭──────────╮   │  ╭─────────╮    ╭─────────╮    ╭─────────╮  │   ╭──────╮ │ Markdown ├─────>│ Pipe #1 ├───>│ Pipe #2 ├───>│ Pipe #n ├─────>│ HTML │ ╰──────────╯   │  ╰─────────╯    ╰─────────╯    ╰─────────╯  │   ╰──────╯                │                                             │                ╰─────────────────────────────────────────────╯ 

Très vite, on se rend compte que toutes les lignes de texte de notre article n’ont pas la même portée et ne réclament pas le même traitement. Pour illustrer cela, on peut par exemple distinguer un paragraphe dans le corps de l’article, d’un bloc de code, ou encore du frontmatter, cet en-tête au format YAML qui déclare les méta-données.

C’est à ce moment précis que toute la lumière se fait sur Enumerable#chunk ! Cette méthode méconnue va nous être d’un grand secours. Que fait-elle ? Elle parcourt les éléments d’un Enumerable en les regroupant en fonction de la valeur de retour d’un bloc qu’on lui passe en argument. En d’autres termes, elle découpe notre article en petits bouts homogènes selon un critère discriminent.

Pour le dire encore autrement, et si l’on m’autorise la comparaison, c’est un peu l’équivalent de String#split pour un Enumerable.

Mettons-nous à table !

À l’instar d’une recette de cuisine nous enjoignant à nous emparer d’un œuf pour en séparer le blanc du jaune, voyons comment Enumerable#chunk peut nous aider à séparer le frontmatter du corps de texte.

Le frontmatter se trouve nécessairement au tout début de notre fichier et est encadré de 3 tirets, comme ceci :

--- author: Jeff B. Cohen <jeff@example.com> title: Titre de l'article description: Elle sera utilisée dans la balise <meta name='description'> ---  Ici commence mon article. 

Imaginons que l’extrait ci-dessus constitue l’intégralité d’un fichier nommé article.md et que nous tâchions d’en extraire le frontmatter. Voici comment nous pourrions procéder. Tout d’abord, écrivons une méthode chunks qui prendra en argument le contenu de notre fichier sous la forme d’une liste de lignes.

SEPARATOR_REGEX = /A---z/.freeze  # Sépare des morceaux de données délimités par des lignes de 3 tirets def chunks(lines, separator: SEPARATOR_REGEX)   lines.chunk do |line|     line.chomp !~ separator   end end 

Nous pouvons ensuite l’utiliser comme ceci :

lines = File.readlines('article.md') chunks(lines).to_a  # [ #  [false, ["---"]], #  [true,  ["author: Jeff B. Cohen <jeff@example.com>", #           "title: Titre de l'article", #           "description: Elle sera utilisée dans la balise <meta name='description'>"]], #  [false, ["---"]], #  [true,  ["", #           "Ici commence mon article."]] # ] 

Qu’avons-nous ? Une liste de listes, contenant chacune deux données : un booléen et un Array. Le booléen représente le résultat de l’expression que contient notre bloc : false si l’on se trouve face à notre séparateur, qui sera isolé dans une liste rien que pour lui ; ou true dans le cas contraire. Tant qu’on ne rencontre pas de nouveau notre séparateur, toutes les lignes qui se présenteront seront regroupées au sein du même Array. On observe bien ici une alternance, séparateur, frontmatter, séparateur, corps de l’article.

La singularité de notre exemple fait que nous ne nous retrouvons jamais avec plusieurs lignes consécutives constituées de 3 tirets. Cela dit, si nous voulions nous assurer que chaque séparateur se retrouve effectivement isolé, il existe un mot-clé forçant ce comportement ! Il s’agit de :_alone. Voyons cela de plus près :

def chunks(lines, separator: SEPARATOR_REGEX)   lines.chunk do |line|     line.chomp !~ separator || :_alone   end end 

Le résultat de notre bloc sera ainsi true ou :_alone. Voici ce que l’on obtient à présent :

lines = File.readlines('article.md') chunks(lines).to_a  # [ #  [:_alone, ["---"]], #  [true, ["author: Jeff B. Cohen <jeff@example.com>", #          "title: Titre de l'article", #          "description: Elle sera utilisée dans la balise <meta name='description'>"]], #  [:_alone, ["---"]], #  [true, ["", #          "Ici commence mon article."]] # ] 

Dans le cas qui nous occupe cependant, il ne nous est pas utile de récupérer le séparateur. Tout ce qui nous intéresse, ce sont nos deux blocs. Ça tombe bien, c’est prévu ! Les valeurs nil ou :_separator, au choix, indiquent que les éléments doivent être ignorés. Adaptons notre méthode chunks et voyons ce que ça donne.

def chunks(lines, separator: SEPARATOR_REGEX)   lines.chunk do |line|     line.chomp !~ separator || nil   end end 

Le résultat de notre bloc sera cette fois true ou nil. Voici ce que l’on obtient à présent :

lines = File.readlines('article.md') chunks(lines).to_a  # [ #  [true, ["author: Jeff B. Cohen <jeff@example.com>", #          "title: Titre de l'article", #          "description: Elle sera utilisée dans la balise <meta name='description'>"]], #  [true, ["", #          "Ici commence mon article."]] # ] 

Pour récupérer le frontmatter, il nous suffit cette fois d’extraire le second élément du premier Array de l’Enumerator que nous renvoie notre méthode chunks :

lines = File.readlines('article.md') _, header = chunks(lines).first puts header  #  ["author: Jeff B. Cohen <jeff@example.com>", #   "title: Titre de l'article", #   "description: Elle sera utilisée dans la balise <meta name='description'>"] 

Un dernier petit morceau

Pour aller plus en finesse, sachez qu’il existe également une méthode Enumerable#chunk_while qui permet de décider où trancher en comparant chaque élément avec le précédent. Faut-il encore en avoir l’usage… mais qui sait !

À lire aussi

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique

Lire la suite

intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 

Lire la suite

Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 

Lire la suite

image miniature les nouveautés Atlassian
26 février 2025

Les nouveautés Atlassian en 2025

Lire la suite

Articles associés

Fresque numérique miniature image
16 avril 2025

Fresque du Numérique


Lire la suite
intelligence artificielle Ouicommit miniature image
17 mars 2025

Ouicommit – L’intelligence artificielle en entreprise, on y est ! 


Lire la suite
Image miniature Hackathon Women in Tech
13 mars 2025

Hackathon Women in Tech :  un engagement pour une tech plus inclusive 


Lire la suite

À propos

  • Qui sommes-nous ?
  • Références
  • RSE
  • Ressources

Offres

  • Applications métier
  • Collaboration des équipes
  • Sécurisation et optimisation du système d’information
  • Transformation numérique

Expertises

  • Développement logiciel
  • DevSecOps
  • Intégration de logiciels et négoce de licences
  • Logiciel de CRM et de gestion
  • UX/UI design
  • Accessibilité Numérique
  • Démarches simplifiées
  • Formations Atlassian

Carrières

  • Pourquoi rejoindre Ouidou ?
  • Nous rejoindre
  • Rencontrer nos collaborateurs
  • Grandir chez Ouidou

SIEGE SOCIAL
70-74 boulevard Garibaldi, 75015 Paris

Ouidou Nord
165 Avenue de Bretagne, 59000 Lille

Ouidou Rhône-Alpes
4 place Amédée Bonnet, 69002 Lyon

Ouidou Grand-Ouest
2 rue Crucy, 44000 Nantes

Ouidou Grand-Est
7 cour des Cigarières, 67000 Strasbourg

  • Linkedin Ouidou
  • GitHub Ouidou
  • Youtube Ouidou
© 2024 Ouidou | Tous droits réservés | Plan du site | Mentions légales | Déclaration d'accessibilité
    Nous contacter