# Var = Array\[0\] : per valore o per riferimento?

**URL:** <https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487>\
**Category:** IT\
**Created:** [July 3, 2009, 12:45pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487 "2009-07-03T12:45:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gionni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ce7236/32.png) [@gionni](https://www.ruby-forum.com/u/gionni)\
**Post date:** [July 3, 2009, 12:45pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487/1 "2009-07-03T12:45:05Z")

</div>

Mi sono trovato a scoprire che nel caso si faccia

list = [[1,0],[1,1]] # =\> [[1, 0], [1, 1]]  
a = list[0] # =\> [1, 0]  
a.delete\_at(0) # =\> 1  
a # =\> [0]  
list # =\> [[0], [1, 1]]

effettuando quindi nell’operazione a=list[0] non assegna il valore, ma  
il riferimento, cosa questa che nella documentazione non avevo trovato.

sorgono quindi le domande

1. questa impostazione vale anche in altri casi?
2. come effettuare invece un passaggio per valore, senza dover fare

list[0].length.times{|i| a[i]=list[0][i]}

passando tutto il sub-array in blocco non per riferimento?

---

<div class="post-metadata">

**Author:** ![gionni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ce7236/32.png) [@gionni](https://www.ruby-forum.com/u/gionni)\
**Post date:** [July 3, 2009, 1:24pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487/2 "2009-07-03T13:24:09Z")

</div>

Ciao Giovanni,

riesco solo a darti una risposta parziale: puoi assegnare ad a il  
sub-array in questo modo:

a = list[0].dup

Così facendo il sub-array originale non verrà toccato, visto che  
lavorerai su una copia.

Ciao,  
Silvano

2009/7/3 Giovanni M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Ml mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.ruby-it.org/mailman/listinfo/ml](http://lists.ruby-it.org/mailman/listinfo/ml)

–  
Considera l’ambiente prima di stampare questa email. Dai, che  
l’equazione è semplice: meno A4, più alberi.

. . . Silvano S. . . .  
email: removed\_email\_address@domain.invalid  
site: [http://www.sistrall.it](http://www.sistrall.it)

---

<div class="post-metadata">

**Author:** ![gionni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ce7236/32.png) [@gionni](https://www.ruby-forum.com/u/gionni)\
**Post date:** [July 3, 2009, 1:35pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487/3 "2009-07-03T13:35:15Z")

</div>

Il giorno 03 Luglio 2009 12.45, Giovanni  
Messina[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) ha scritto:

> sorgono quindi le domande
> 
> 1. questa impostazione vale anche in altri casi?

metterla in termini di passaggio per valore o per riferimento rischia  
più che altro di confondere le idee; la questione è molto più  
semplice: bisogna vedere cosa stai facendo: creando un oggetto nuovo o  
modificando un oggetto.

esempio concreto:  
a = “ciao”  
b = a  
a = a.upcase  
a =\> “CIAO”  
b =\> “ciao”

qui non modifichi a, ma lo riassegni.

invece:

a = “ciao”  
b = a  
a.upcase!  
a =\> “CIAO”  
b =\> “CIAO”

ogni volta che fai questo = quello stai solo creando un riferimento;  
ogni volta che fai  
questo.metodo\_che\_modifica\_questo\_invece\_di\_creare\_un\_nuovo\_oggetto(),  
modifichi l’oggetto, che quindi sarà diverso da qualunque riferimento  
si parta per arrivarci.

altro esempio (un errore che commettevo spessissimo anche in python):  
a = [[1]] \* 5  
a =\> [[1], [1], [1], [1], [1]]  
b = a  
b =\> [[1], [1], [1], [1], [1]]  
a[0] \<\< 3  
a =\> [[1, 3], [1, 3], [1, 3], [1, 3], [1, 3]]  
b =\> [[1, 3], [1, 3], [1, 3], [1, 3], [1, 3]]

nota che non solo ho modificato b modificando a, ma ogni elemento di a  
(o di b) è stato modificato.

questo perché \<\< è un metodo che modifica l’oggetto.

per eliminare ogni dubbio c’è il metodo object\_id. ad esempio,  
nell’irb che ho aperto in questo momento:

a.object\_id =\> 30095320  
b.object\_id =\> 30095320

ma, soprattutto:  
a.collect {|x| x.object\_id} =\> [30095330, 30095330, 30095330,  
30095330, 30095330]

ovvero, a è un oggetto di tipo array che contiene 5 elementi, i quali  
sono 5 riferimenti allo stesso oggetto, cioè [1, 3].

> 1. come effettuare invece un passaggio per valore, senza dover fare
> 
> list[0].length.times{|i| a[i]=list[0][i]}

sui singoli oggetti puoi usare clone o dup (credo siano alias); però  
dup bara, duplica l’oggetto esterno ma non quelli interni:

a = [[1], [1], [1], [1], [1]]  
b = a  
c = a.dup  
a \<\< 2  
a =\> [[1], [1], [1], [1], [1], 2]  
b =\> [[1, 2], [1], [1], [1], [1], 2]  
c =\> [[1], [1], [1], [1], [1]]

però:a[0] \<\< 3  
a =\> [[1, 3], [1], [1], [1], [1], 2]  
b =\> [[1, 3], [1], [1], [1], [1], 2]  
c =\> [[1, 3], [1], [1], [1], [1]]

non so se esiste un metodo già definito per fare la “copia profonda”  
di un oggetto; se non esiste, devi farlo tu a mano.

pietro

---

<div class="post-metadata">

**Author:** ![gionni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ce7236/32.png) [@gionni](https://www.ruby-forum.com/u/gionni)\
**Post date:** [July 3, 2009, 7:37pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487/4 "2009-07-03T19:37:33Z")

</div>

Giovanni M. wrote:

> grazie per le spiegazioni chiare ed esaustive 🙂
> 
> Se poi per caso qualcuno sa di un metodo per la “copia profonda” …
> 
> Giovanni

Non esiste un metodo per la “copia profonda” per una semplice ragione,  
molti oggetti sono instanziati al momento della richiesta (immagina di  
avere un oggetto activerecord con dei collegamenti tipo:

Persona  
has\_many :indirizzi

Indirizzo  
has\_many :numeri\_telefono

quando hai una persona i numeri di telefono non sono ancora caricati, si  
caricano nel momento in cui fai persona.indirizzi[x].numeri\_telefono  
quindi non puoi clonare oggetti che ancora non ci sono (per altro mi  
sembra di aver letto che puoi specificare fino a che livello  
active\_record arriva a leggere quando instanzi un oggetto)

---

<div class="post-metadata">

**Author:** ![gionni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/ce7236/32.png) [@gionni](https://www.ruby-forum.com/u/gionni)\
**Post date:** [July 3, 2009, 2:17pm UTC](https://www.ruby-forum.com/t/var-array-0-per-valore-o-per-riferimento/171487/5 "2009-07-03T14:17:07Z")

</div>

grazie per le spiegazioni chiare ed esaustive 🙂

Se poi per caso qualcuno sa di un metodo per la “copia profonda” …

Giovanni
