From: Rick DeNatale Date: 2009-12-22T22:18:50+09:00 Subject: Re: Ruby's implementation of Fixnum-assignment On Tue, Dec 22, 2009 at 3:24 AM, Robert Klemme wrote: > 2009/12/21 RichardOnRails : >> 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. Absolutely correct! >> 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.1b Otherwise: >> 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: > > 1. Make sure local scope has a place for variable "a". > 2. Evaluate the expression to the right side of "=". > 3. 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. A very good way to express this I think. >> 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 >> QED??? > > 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 > out. > > 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. These things are artifacts of the implementation of the language. I believe that in MRI the object_id is just the reference value 'cast' to a FixNum (or maybe Integer). So for an immediate object it's a particular bit pattern interpreted as an integer, and for boxed objects it's the address of the object's state interpreted as an integer. But this doesn't need to be the case, in an implementation which used a different object model for, say GC, and which interposed an indirection, then boxed objects might have an object id field kept with the indirection, so that the object state could be moved without affecting the object_id. Other Ruby implementations like JRuby, Rubinius, Maglev ... might implement such stuff in a way similar to MRI, possible with subtle variations, or some might do it radically differently. > 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. > Agreed, the only time it's really important is edge-cases, and when writing extensions. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale