On Dec 21, 12:26 pm, Robert K. firstname.lastname@example.org wrote:
2009/12/21 RichardOnRails email@example.com:
- “… an object in Ruby has an identity: “abc”object_id
This object ID is of limited utility." [“The Ruby Way”, Second
Edition, Fulton, p.26]
As Marnen pointed out already, there is no contradiction between what
I said and what the authorities said. A variable is just a place to
store an object reference. Other than that it does not have
properties, definitively no id. What is returned by invocation of
#object_id is attached to the object at hand and not to the variable.
Whether the object is an immediate value such as a Fixnum or a
“regular” object (such as String) does not really matter with regard
to the variable.
step 3 actually mixes two separate things: evaluation of the expression of the right side of “=” and assignment
Granted, I stuck to what I viewed as the essential issues. Perhaps a
more complete estimate might read.
3.1 Ruby interprets “a = 1” to mean “a.=(1)”, i.e. invokes the “=”
method on the object. Normally, that reference will cascade up to
Object.=, I suppose.
Now that is completely wrong. “a=1” is an assignment meaning, it
takes whatever object reference the evaluation of the expression on
the right side yields and puts it into the storage location denoted by
“a”. There is no method invoked, certainly no method on “a” which -
as I said - is no object but just a place in storage.
3.1a If “a” is undefined in the current scope, “a” will be added to
the scope with an ID of (2a+1) = 3.
3.1.b.1 If a’s ID is in the range of Fixnums, (or a’s ID indicates
it’s true, false, etc .), a’s ID will be set to 3
3.1b.2 Otherwise, if a’s ID indicates any other type, a’s ID will be
pushed to the garbage stack and a’s ID will be set to 3
Is that better?
I’m sorry, no. It’s rather:
- Make sure local scope has a place for variable “a”.
- Evaluate the expression to the right side of “=”.
- Take the resulting object reference of step 2 and store it in the
location for variable “a”.
Steps 1 and 2 can actually be exchanged, it does not really matter much.
For optimization purposes some object references are special in that they actually are the object
That sounds like you mean in the case of Fixnum “1”, that the number
1 IS the ID as well as the value of the object. But we can see “puts
1.object_id” => 3
No, it means that in the case of Fixnum the reference is the object.
See the article Gary referenced for further detail:
So I think that fact (plus all the other evidence I offered) suggests
that ID’s for Fixnum’s are manufactured as 2*value+1
The way object ids come into existence is completely unrelated to the
process of variable assignment. Since in Ruby any object needs an id
and Fixnums (plus a few more) are immediate values (which means there
is just an object reference and no object, which btw also means that
there is no place to store state and hence Fixnums are immutable) it
was chosen to derive object ids according to the formula you found
There is probably also a technical reason for this formula which
likely has to do with the fact that other objects need ids as well and
calculation of them should be efficient but I believe it is more
important to understand the object - object reference dichotomy.
Actually, I believe all this reasoning about Fixnums being immediate
values is totally overdone. From a Ruby programmer’s perspective it
is completely irrelevant (if you put performance aside for the
moment). It is sufficient to know that Ruby has variables which
contain object references and that evaluation of whatever expression
yields an object reference. The programming model is as simple as
that. Immediate values are really just an optimization under the hood
to speed up math and other common operations. In Ruby land, you have
no chance to distinguish an immediate value from any other immutable
object - whatever methods you invoke (and there are quite a few for
Fixnum) the object simply does not change its state. Granted, there
are a few things that do not work, for example defining a finalizer
for a Fixnum but even that raises an ordinary exception.