Now that we've gone to the trouble to create all these objects,
let's make sure we don't lose them. Variables are used to keep track
of objects; each variable holds a reference to an object.
Let's confirm this with some code.
person = "Tim"
|
person.id
|
� |
537771100
|
person.type
|
� |
String
|
person
|
� |
"Tim"
|
On the first line, Ruby creates a new
String
object with the
value ``Tim.'' A reference to this object is placed in the local
variable
person
.
A quick check shows that the variable has indeed taken on the
personality of a string, with an object id, a type, and a value.
So, is a variable an object?
In Ruby, the answer is ``no.'' A variable is simply a reference to an
object. Objects float around in a big pool somewhere (the heap, most
of the time) and are pointed to by variables.
Let's make the example slightly more complicated.
person1 = "Tim"
|
person2 = person1
|
|
person1[0] = 'J'
|
|
person1
|
� |
"Jim"
|
person2
|
� |
"Jim"
|
What happened here? We changed the first character of
person1
, but both
person1
and
person2
changed from ``Tim'' to ``Jim.''
It all comes back to the fact that variables hold references to
objects, not the objects themselves. The assignment of
person1
to
person2
doesn't create any new objects; it simply copies
person1
's object reference to
person2
, so that both
person1
and
person2
refer to the same object. We show
this in Figure 3.1 on page 31.
Assignment
aliases objects, potentially giving you multiple
variables that reference the same object.
But can't this cause problems in your code? It can, but not
as often as you'd think (objects in Java, for example, work exactly
the same way). For instance, in the example in Figure
3.1, you could avoid aliasing by using the
dup
method of
String
, which creates a new
String
object with identical
contents.
person1 = "Tim"
|
person2 = person1.dup
|
person1[0] = "J"
|
person1
|
� |
"Jim"
|
person2
|
� |
"Tim"
|
You can also prevent anyone from changing a particular object by
freezing it (we talk more about freezing objects
on page 251). Attempt to alter a frozen object, and Ruby
will raise a
TypeError
exception.
person1 = "Tim"
person2 = person1
person1.freeze # prevent modifications to the object
person2[0] = "J"
|
produces:
prog.rb:4:in `=': can't modify frozen string (TypeError)
from prog.rb:4
|