2011-01-09 15 views
5

Come indicato in this answer, Array.new(size, object) crea un array con i riferimenti size allo stesso object.In Ruby, perché Array.new (dimensione, oggetto) crea una matrice costituita da più riferimenti allo stesso oggetto?

hash = Hash.new 
a = Array.new(2, hash) 
a[0]['cat'] = 'feline' 
a # => [{"cat"=>"feline"},{"cat"=>"feline"}] 
a[1]['cat'] = 'Felix' 
a # => [{"cat"=>"Felix"},{"cat"=>"Felix"}] 

Perché Rubino fare questo, piuttosto che fare un dup o clone di object?

risposta

9

Perché è quello che dice the documentation. Si noti che Hash.new è solo essere chiamato una volta, così, naturalmente, non c'è un solo Hash

Se si desidera creare un nuovo oggetto per ogni elemento della matrice, passare un blocco al metodo Array.new, e quel blocco si chiamerà per ogni nuovo elemento:

>> a = Array.new(2) { Hash.new } 
=> [{}, {}] 
>> a[0]['cat'] = 'feline' 
=> "feline" 
>> a 
=> [{"cat"=>"feline"}, {}] 
>> a[1]['cat'] = 'Felix' 
=> "Felix" 
>> a 
=> [{"cat"=>"feline"}, {"cat"=>"Felix"}] 
+2

"Perché è così che dice la documentazione." - Speravo di inserire il motivo per cui un po 'più in là. –

+1

Popping dello stack perché: quando si passa un oggetto da utilizzare per precompilare l'array, l'array verrà prepopolato con tale oggetto. – yfeldblum

+0

@Justice: Eri serio o sarcastico con quel commento? –

2

Per alcune classi che non possono essere modificati in-place (come Fixnum s) sotto forma Array.new(X, object) funziona come previsto ed è probabilmente più efficiente (si chiama semplicemente memfill invece di rb_ary_store e yield ing al blocco):

Per oggetti più complicati hai sempre la forma a blocchi (ad es. Array.new(5) { Hash.new }).

* Modifica: * Modificato in base ai commenti. Scusa per lo stupido esempio, ero stanco quando l'ho scritto.

+1

Stai sostituendo c [1] con un nuovo oggetto, piuttosto che modificarlo. –

+0

>> c [1] << "h"; C#=> ["ah", "ah", "ah", "ah", "ah"] – Nemo157

+0

Scusa, ho scritto quella risposta proprio prima di andare a letto, hai ragione, ovviamente. Il resto dovrebbe essere ancora vero. –

Problemi correlati