The first thing that really surprised me today was the flexibility of Ruby's shovel operator, <<. A student in the class had tried the following:
a = [0]
a << aWhat do you think a is now? I was sure it would be [0, [0]]. But lo and behold, Ruby sparkles;
a = [0]
a << a
=> [0, [...]]Whoa... [...]? What is that? Let's try this;
a[1]
=> [0, [...]]...Huh. It seems that a[1] == a. The second entry in the array is the same thing as the array. How is that possible? It's only possible if a is infinite.
How does Ruby handle this? Here's my guess.
First let's consider the difference between reference and value. A reference is something that refers to something else. A reference can refer to another reference, or it can refer to a value. All variables are references; they refer to some value somewhere (or they refer to a reference which refers to a value eventually...). A value is a literal. So a value will be a number, or a string, or an array, et cetera. When we write a = [0], we tell the computer to make the variable a refer to the value [0]. When we write b = a, we tell the computer to make the variable b refer to whatever a eventually refers to--in this case [0].
Based on the behavior above, the shovel operator a << b must say, "make a new last entry of a and make that last entry refer to whatever b refers to." The alternative I expected was, "...make that last entry refer to the value of what b refers to."
So in the case of our infinite array, the second element a[1] is a reference to a itself. Normally this would be a problem in a programming languages. Ruby must have some kind of self-reference detection that converts these into meaningful objects.
Good stuff