JnBrymn
JnBrymn

Reputation: 25383

Learning Ruby: Making infinite dimensional array via block abuse

Somebody tell me what's going on here:

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

The result is [[...], [...], [...]]. And if I evaluate a[0] I get [[...], [...], [...]]. And if I evaluate a[0][0] I get [[...], [...], [...]] ad infinitum.

Have I created an array of infinite dimensionality? How/Why should this possibly work?

Upvotes: 1

Views: 251

Answers (2)

Theo
Theo

Reputation: 132972

Basically you've modified every element in a to reference the list itself. The list is recursively referencing itself:

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
...

(# => is a Rubyism for "this line evaluates to")

Depending on how you look at it it is not infinite. It's more or less just like a piece of paper with the words "please turn over" written on both sides.

The reason that Ruby prints [...] is that it is clever enough to discover that the list is recursive, and avoids going into an infinite loop.

By the way, your usage of each is a bit non-idiomatic. each returns the list, and you usually don't assign this return value to a variable (since you already have a variable referencing it, a in this case). In other words, your code assigns [0,1,2] to a, then loops over a (setting each element to a), then assigns a to a.

Upvotes: 3

Satya
Satya

Reputation: 4478

I think it's a self-referential data structure. The a[x]=a puts a's pointer in a[x].

Upvotes: 1

Related Questions