Ref

Une ref est une identité englobant une valeur. Au même titre qu'un atom, il s'agit d'une référence sur cette dernière. Les ref peuvent être modifiées mais uniquement au travers d'une transaction dans la Sofware Transactional Memory (STM).

Elles remplacent les atom lorsquent des modifications coordonnées sur plusieurs éléments sont requises.

Opérations de base

Une ref se définit via le symbole ref, qui prend en paramètre l'état de la ref.

(def account (ref 1000))

Pour intéragir avec une ref, il est nécessaire de se trouver dans une transaction dans la STM. Ceci s'effectue grâce à dosync. L'utilisation de la STM n'a de sens que si l'on tente de manipuler plusieurs refs et que ces opérations doivent être réalisées de manière atomiques.

(dosync
  (alter account1 #(+ % 100))
  (alter account2 #(- % 100)))

La modification de la ref se fait avec alter qui prend en premier paramètre la ref et comme second paramètre une fonction à appliquer. Si une autre transaction venait à modifier account1 ou account2 avant que celle-ci se termine, la transaction sera automatiquement relancée.

Si l'ordre dans lequel s'effectue les opérations n'a pas d'importance, il est alors possible d'utiliser commute

(dosync
  (commute account1 #(+ % 100))
  (commute account2 #(- % 100)))

Une ref peut-être réinitialisé (toujours dans une transaction) grâce à ref-set.

(dosync
  (ref-set account1 0)
  (ref-set account2 0))

Attention

Les transactions pouvant potentiellement se relancer plusieurs fois, leur utilisation n'est pas recommandée pour les opérations qui provoquent des effets de bord (I/O).

Précédent - Suivant -

powered by mcorbin - Available on Github