Le module Agent fournit une abstraction pour lancer des processus et la boucle receive-send. Désormais, on appellera « agent processes » les processus démarrés avec le module Agent. On peut choisir un agent process pour représenter un état partagé central.
Pour démarrer un agent process, Agent fournit la fonction start/2. La fonction que l'on fournit à start pour démarrer l'agent process renvoie l'état initial du processus :
# Start an agent process with an initial value of an empty list
{:ok, agent_pid} = Agent.start(fn -> [] end)
Tout comme Map ou List, Agent fournit de nombreuses fonctions pour manipuler les agent processes.
Il est d'usage d'organiser et d'encapsuler toutes les fonctionnalités liées à Agent dans un module dédié au domaine que l'on modélise.
Ton association de quartier t'a demandé d'implémenter une application simple de registre pour gérer les inscriptions au jardin communautaire. La structure Plot t'a déjà été fournie.
Implémente la fonction CommunityGarden.start/1 ; elle doit recevoir une liste de mots-clés d'options facultatives à transmettre au processus agent. L'état initial du jardin doit être initialisé pour représenter une collection vide de parcelles. Elle doit renvoyer un tuple :ok avec le pid du jardin.
{:ok, pid} = CommunityGarden.start()
# => {:ok, #PID<0.112.0>}
Implémente la fonction CommunityGarden.list_registrations/1. Elle doit recevoir le pid du jardin communautaire. Elle doit renvoyer la liste des parcelles enregistrées.
CommunityGarden.list_registrations(pid)
# => []
À ce stade, on n'a pas encore ajouté la possibilité d'enregistrer une parcelle, donc cette liste doit être vide
Implémente la fonction CommunityGarden.register/2. Elle doit recevoir le pid du jardin communautaire et un nom auquel enregistrer la parcelle. En cas de succès, elle doit renvoyer la structure Plot avec l'identifiant de la parcelle et la personne à qui elle est enregistrée.
Les identifiants doivent être incrémentaux et uniques. Tu peux conserver un compteur d'identifiants dans l'état de l'agent.
CommunityGarden.register(pid, "Emma Balan")
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
CommunityGarden.list_registrations(pid)
# => [%Plot{plot_id: 1, registered_to: "Emma Balan"}]
Implémente la fonction CommunityGarden.release/2. Elle doit recevoir le pid et l'id de la parcelle à libérer. Elle doit renvoyer :ok en cas de succès. Quand une parcelle est libérée, son identifiant n'est pas réutilisé ; il sert uniquement d'identifiant unique.
CommunityGarden.release(pid, 1)
# => :ok
CommunityGarden.list_registrations(pid)
# => []
Implémente la fonction CommunityGarden.get_registration/2. Elle doit recevoir le pid et l'id de la parcelle à vérifier. Elle doit renvoyer la parcelle si elle est enregistrée, et :not_found si elle ne l'est pas.
CommunityGarden.get_registration(pid, 1)
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
CommunityGarden.get_registration(pid, 7)
# => {:not_found, "plot is unregistered"}
Inscris-toi sur Exercism pour apprendre et maîtriser Elixir avec 58 concepts168 exercices, et un vrai mentorat humain, le tout gratuitement.