Il modulo Agent fornisce un'astrazione per avviare processi e il ciclo receive-send. Da qui in avanti chiameremo «processi agente» i processi avviati tramite il modulo Agent. Un processo agente può essere scelto per rappresentare uno stato condiviso centrale.
Per avviare un processo agente, Agent mette a disposizione la funzione start/2. La funzione che passi a start quando avvii il processo agente restituisce lo stato iniziale del processo:
# Start an agent process with an initial value of an empty list
{:ok, agent_pid} = Agent.start(fn -> [] end)
Proprio come Map o List, Agent fornisce molte funzioni per lavorare con i processi agente.
È prassi comune organizzare e incapsulare tutte le funzionalità legate ad Agent in un modulo dedicato al dominio che stiamo modellando.
La tua associazione di quartiere ti ha chiesto di realizzare una semplice applicazione di registro per gestire le registrazioni dell'orto comunitario. La struct Plot è già stata fornita.
Implementa la funzione CommunityGarden.start/1: deve ricevere una keyword list facoltativa di opzioni da inoltrare al processo agent. Lo stato iniziale dell'orto va inizializzato in modo che rappresenti una collezione vuota di appezzamenti. Deve restituire una tupla :ok con il pid dell'orto.
{:ok, pid} = CommunityGarden.start()
# => {:ok, #PID<0.112.0>}
Implementa la funzione CommunityGarden.list_registrations/1. Deve ricevere il pid dell'orto comunitario. Deve restituire una lista degli appezzamenti memorizzati che sono registrati.
CommunityGarden.list_registrations(pid)
# => []
A questo punto, non abbiamo ancora aggiunto la possibilità di registrare un appezzamento, quindi questa lista dovrebbe essere vuota
Implementa la funzione CommunityGarden.register/2. Deve ricevere il pid dell'orto comunitario e un nome a cui registrare l'appezzamento. In caso di successo, deve restituire la struct Plot con l'id dell'appezzamento e la persona a cui è registrato.
Gli id devono essere incrementali e unici. Puoi tenere un contatore di id nello stato dell'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"}]
Implementa la funzione CommunityGarden.release/2. Deve ricevere il pid e l'id dell'appezzamento da rilasciare. Deve restituire :ok in caso di successo. Quando un appezzamento viene rilasciato, l'id non viene riutilizzato: serve solo come identificatore unico.
CommunityGarden.release(pid, 1)
# => :ok
CommunityGarden.list_registrations(pid)
# => []
Implementa la funzione CommunityGarden.get_registration/2. Deve ricevere il pid e l'id dell'appezzamento da controllare. Deve restituire l'appezzamento se è registrato, e :not_found se non è registrato.
CommunityGarden.get_registration(pid, 1)
# => %Plot{plot_id: 1, registered_to: "Emma Balan"}
CommunityGarden.get_registration(pid, 7)
# => {:not_found, "plot is unregistered"}
Iscriviti a Exercism per imparare e padroneggiare Elixir con 58 concetti168 esercizi e il mentoring di persone reali, tutto gratis.