# Set e Get

Sonic Pi ha un archivio globale di memoria chiamato Time State. Le due cose principali che fai con questo sono `set` (impostare) e `get` (richiamare) informazioni. Immergiamoci di più…

## Set

Per impostare informazioni nel Time State abbiamo bisogno di due cose:

1. le informazioni che vogliamo impostare,
2. un nome unico (la chiave) per le informazioni.

Per esempio, forse vogliamo impostare il numero `3000` sotto la chiave `:intensity`. Questo è possibile utilizzano la funzione `set`:

    set :intensity, 3000

Possiamo usare qualsiasi nome per la chiave. Se si sono già impostate informazioni con quella chiave, il nuovo `set` le sostituisce:

    set :intensity, 1000
    set :intensity, 3000

Nell’esempio sopra, visto che abbiamo memorizzato tutti e due i numeri sotto la stessa chiave, “vince” l’ultima chiamata di `set`, così il numero associato con `:intensity` sarà `3000` perché la prima chiamata di `set` è in effetti soprascritta.

## Get

Per recuperare informazioni dal Time State abbiamo bisogno solamente della chiave usata per fare il `set`; in questo caso, `:intensity`. Poi, basta che chiamiamo `get[:intensity]`, che possiamo verificare facilmente stampandone il risultato sul log:

    print get[:intensity] #=> stampa 3000

Nota che le chiamate a `get` possono restituire informazioni che erano `set` da una esecuzione precedente. Una volta impostata una informazione con `set`, è disponibile fino a quando non viene soprascritta (come sopra abbiamo rimpiazzato il valore `1000` di `:intensity` con `3000`) o fino a quando non viene chiuso Sonic Pi.

## Thread multipli

Il beneficio principale del sistema Time State è che si può usare senza rischi attraverso thread o cicli vivi. Per esempio, puoi avere un ciclo vivo che imposta informazioni ed un altro che le recupera:

    live_loop :setter do
      set :foo, rrand(70, 130)
      sleep 1
    end
    live_loop :getter do
      puts get[:foo]
      sleep 0.5
    end

Una cosa bella dell’uso di `get` e `set` in questo modo attraverso i thread è che genera sempre lo stesso risultato ogni volta che premi “Run”. Dai, provalo. Vedi se ottieni il seguente nel tuo log:

    {run: 0, time: 0.0}
     └─ 125.72265625
    {run: 0, time: 0.5}
     └─ 125.72265625
    {run: 0, time: 1.0}
     └─ 76.26220703125
    {run: 0, time: 1.5}
     └─ 76.26220703125
    {run: 0, time: 2.0}
     └─ 114.93408203125
    {run: 0, time: 2.5}
     └─ 114.93408203125
    {run: 0, time: 3.0}
     └─ 75.6048583984375
    {run: 0, time: 3.5}
     └─ 75.6048583984375

Prova ad eseguire alcune volte — vedi, è uguale ogni volta. Questo si chiama comportamento deterministico ed è importantissimo quando vogliamo condividere la nostra musica in forma di codice e sapere che la persona che la esegue sente esattamente quello che abbiamo voluto che sentisse (come un MP3 o un flusso di internet suona lo stesso per tutti gli ascoltatori).

## Un Sistema Semplice di Stato Deterministico

Nella Sezione 5.6 abbiamo parlato della ragione perché usare variabili attraverso thread può causare comportamento casuale. Questo ci blocca da potere riprodurre code come questo in maniera affidabile:

    ## Un Esempio di Comportamento Non-Deterministico
    ## (dovuto a condizioni di gara causate da vari
    ## cicli vivi che manipolano lo stesso variabile allo
    ## stesso tempo).
    ##
    ## Se esegui questo codice noterai
    ## che l'elenco che viene stampato non
    ## è sempre in ordine!
    a = (ring 6, 5, 4, 3, 2, 1)
    live_loop :shuffled do
      a = a.shuffle
      sleep 0.5
    end
    live_loop :sorted do
      a = a.sort
      sleep 0.5
      puts "sorted: ", a
    end

Guardiamo come possiamo fare questo con `get` e `set`:

    ## Un Esempio di Comportamento Deterministico
    ## (nonostante accesso concorrente dello
    ## stato condiviso) usando il nuovo sistema
    ## Time State di Sonic Pi.
    ##
    ## Quando questo codice si esegue, l'elenco che
    ## viene stampato è sempre in ordine!
    ##
    set :a, (ring 6, 5, 4, 3, 2, 1)
    live_loop :shuffled do
      set :a, get[:a].shuffle
      sleep 0.5
    end
    live_loop :sorted do
      set :a, get[:a].sort
      sleep 0.5
      puts "sorted: ", get[:a]
    end

Nota che questo codice è quasi uguale alla versione prima che usava un variabile. Ma quando esegui questo codice, si comporta come si aspetta con qualsiasi codice tipico di Sonic Pi — fa la stessa cosa ogni volta in questo caso, grazie al sistema Time State.

Dunque, quando si condividono informazioni fra cicli vivi e thread, usa `get` e `set` invece di variabili per avere comportamento deterministico e riproducibile.