Lentilles

Dans les chapitres précédents Objets et immutabilité et Tableaux et immutabilité, nous avons appris comment lire, mettre à jour et transformer les propriétés d'un objet et des éléments d'un tableau d'une façon déclarative et immutable.

Ramda offre un outil plus générique pour effectuer ces opérations: la lentille (NDT: lens en anglais, la lentille d'une longue-vue).

Qu'est-ce qu'une lentille?

Une lentille combine une fonction getter et une fonction setter en une seule unité. Ramda fournit un ensemble de fonctions pour travailler avec les lentilles.

On peut voir un lentille comme quelque chose qui fait le point sur une partie spécifique d'une structure de données plus grande.

Comment puis-je créer une lentille?

La façon la plus générique de créer une lentille en Ramda est d'utiliser la fonction lens (NDT: lentille, en anglais). lens prend une fonction getter et une fonction setter, et renvoie la nouvelle lentille.

const person = {
  name: 'Randy',
  socialMedia: {
    github: 'randycoulman',
    twitter: '@randycoulman'
  }
}

const nameLens = lens(prop('name'), assoc('name'))
const twitterLens = lens(
  path(['socialMedia', 'twitter']),
  assocPath(['socialMedia', 'twitter'])
)

Ici nous utilisons prop et path comme fonctions getter et assoc et assocPath comme fonctions setter.

Remarquez que nous avons à chaque fois dû dupliquer les arguments de la fonction getter dans la fonction setter. Heureusement, Ramda a de beaux raccourcis pour les usages les plus communs des lentilles: lensProp, lensPath et lensIndex.

  • lensProp crée une lentille qui fait le point sur une propriété d'un objet,
  • lensPath crée une lentille qui fait le point sur une propriété imbriquée d'un objet,
  • lensIndex crée une lentille qui fait le point sur un élément d'un tableau.

Nous pourrions réécrire nos précédentes lentilles avec lensProp et lensPath:

const nameLens = lensProp('name')
const twitterLens = lensPath(['socialMedia', 'twitter'])

C'est bien plus simple et supprime la duplication. Je n'éprouve pratiquement jamais le besoin d'utiliser la fonction lens générique.

Que puis-je en faire?

Bon, super, nous avons créer des lentilles. Que peut-on en faire?

Ramda fournit trois fonctions pour travailler avec des lentilles.

  • view lit la valeur d'une lentille,
  • set met à jour la valeur d'une lentille,
  • over applique une fonction de transformation à la lentille.
view(nameLens, person) // => 'Randy'

set(twitterLens, '@randy', person)
// => {
//   name: 'Randy',
//   socialMedia: {
//     github: 'randycoulman',
//     twitter: '@randy'
//   }
// }

over(nameLens, toUpper, person)
// => {
//   name: 'RANDY',
//   socialMedia: {
//     github: 'randycoulman',
//     twitter: '@randycoulman'
//   }
// }

Notez que set et over renvoient l'objet entier avec la propriété visée par la lentille modifiée comme demandé.

Conclusion

Les lentilles peuvent être pratiques si nous avons une structure donnée assez complexe que nous voulons abstraire du code appelant. Plutôt que d'exposer sa structure, ou de fournir un getter, un setter et un transformer pour chaque propriété accessible, on peut donner des lentilles.

Le code client peut alors travailler sur la structure de données en utilisant view, set et over sans être couplé à la forme exacte de la structure.

Chapitre suivant

Nous savons maintenant beaucoup de choses sur ce qu'offre Ramda; certainement assez pour faire la plupart des choses dont nous avons besoin dans nos programmes. Le Récapitulatif revient sur tous les chapitres et mentionne quelques sujets que nous pourrions vouloir explorer nous-mêmes.

results matching ""

    No results matching ""