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 =  a << a
What do you think
a is now? I was sure it would be
[0, ]. But lo and behold, Ruby sparkles;
a =  a << a => [0, [...]]
[...]? What is that? Let's try this;
a => [0, [...]]
...Huh. It seems that
a == 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 = , we tell the computer to make the variable
a refer to the value
. When we write
b = a, we tell the computer to make the variable
b refer to whatever
a eventually refers to--in this case
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 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.