2011-01-17 4 views
1

Jemand sagt mir, was hier los ist:Learning Ruby-: Herstellung unendlichdimensionalen Array über Block Missbrauch

a = [0,1,2] 
a.each {|x| a[x] = a} 

Das Ergebnis [[...], [...], [...]] ist. Und wenn ich a[0] auswerte, bekomme ich [[...], [...], [...]]. Und wenn ich a[0][0] auswerte, bekomme ich [[...], [...], [...]] ad infinitum.

Habe ich ein Array von unendlicher Dimensionalität erstellt? Wie/Warum sollte das funktionieren?

+0

Warum nicht? an der Position a [x] findest du ein, auf dem du wieder ein [x] nennen kannst, etc., etc. Dimensionalität hat immer auch mit Orthogonalität zu tun. Diese Prämisse ist hier nicht gegeben. – flq

+1

Beachten Sie, dass dies nichts mit Blöcken zu tun hat. 'a = []; a [0] = a; a [1] = a; a [2] = a 'wird genau das gleiche Ergebnis haben. – sepp2k

+0

Mit Blöcken können Sie (nicht ganz) ein unendliches dimensionales Array erstellen: 'blk = proc {| i | Array.new (10, & blk)}; a = Array.new (10, & blk) '. Dies führt jedoch zu einem SystemStackError, da Ruby keine unendliche Rekursion verarbeiten kann. – Nemo157

Antwort

3

Grundsätzlich haben Sie jedes Element in a geändert, um die Liste selbst zu referenzieren. Die Liste wird sich selbst rekursiv Referenzierung:

a[0] # => a 
a[0][0] # => a[0], which is a 
a[0][0][0] # => a[0][0], which is a[0], which is a 
... 

(# => ist ein Rubyism für „diese Zeile ausgewertet“)

Je nachdem wie man es sehen es nicht unendlich ist. Es ist mehr oder weniger wie ein Stück Papier mit den Worten "Bitte umdrehen" auf beiden Seiten geschrieben.

Der Grund, dass Ruby [...] druckt, ist, dass es clever genug ist, um zu entdecken, dass die Liste rekursiv ist und vermeidet, in eine Endlosschleife zu gehen.

Übrigens ist Ihre Verwendung von each ein bisschen nicht idiomatisch. each gibt die Liste zurück, und normalerweise weisen Sie diesen Rückgabewert keiner Variablen zu (da Sie bereits eine Variable haben, die darauf verweist, a in diesem Fall). Mit anderen Worten, Ihr Code ordnet [0,1,2] zu a, dann Schleifen über a (Einstellung jedes Element auf a), dann weist a zu a.

+0

Ah ... Ich verstehe. Ich glaube nicht, dass ich jemals mit einer Sprache gespielt habe, in der du das tun konntest. – JnBrymn

+2

@John: Sie können dies in fast jeder Sprache tun. Einschließlich C, C++ (mit expliziten Zeigern oder Referenzen), Java, C#, Python und vielen anderen. – sepp2k

+0

Ah ... Ich verstehe. Und ich fange an, mich irgendwie dumm zu fühlen. Im Nachhinein dürfte das alles offensichtlich gewesen sein. – JnBrymn

1

Ich denke, es ist eine selbstreferentielle Datenstruktur. Das a [x] = a setzt den Zeiger in a [x].