From: Robert Klemme Date: 2005-01-11T02:21:22+09:00 Subject: Re: Immediate values "itsme213" schrieb im Newsbeitrag news:MtyEd.23363$3m6.22017@fe2.texas.rr.com... > > "Bertram Scharpf" wrote > > Am Montag, 10. Jan 2005, 21:09:03 +0900 schrieb Kaspar Schiess: > > > Ruby variables hold references to objects. > > > > Stricly spoken, Fixnums don't. They are treated a special > > way. > > You can try to work the angle that value-like things (Fixnums) are > fundamentally different from objects, but I think there is a simpler > explanation. Along the general lines some others have said in this thread, > but with some differences. > > A variable always 'holds' ('contains', 'its value is') a _reference_ to an > object. This is true for local variables, instance variables, encoded > instance variables (see below), integer-indexed variables array members, > key-indexed variabels like hash entries, global variables. In fact, it is > even true for Constants; I like to think of all of these as 'slots'; some > slots may be 'frozen', ... i.e. they can never refer to a different object > (see below). Although I agree with the rest of your detailed explanation I beg to differ on this one: "they" refers to variables and constants and *every* variable and constant can be made to point to another object: >> Foo = 1 => 1 >> Foo => 1 >> Foo = 2 (irb):2: warning: already initialized constant Foo => 2 >> Foo => 2 You probably wanted to say that for some classes there is just one instance of a specific value: >> 1.id => 3 >> (3 - 2).id => 3 >> (200 / 100 / 2).id => 3 >> (0.5 * 2).to_i.id => 3 So the fixnum representing the number 1 is always represented by the same instance. (As you point out below, technically it's more complicated because the "instance" is different from other classes instances, but from the perspective of the user this doesn't matter as long as he does not try to define methods for 1.) > Most references are encoded as in-memory pointers to heap-allocated storage > corresponding to that object. That heap allocated storage, in turn, contains > a its own 'variables' (called instance variables), which also always 'hold' > references to objects. Methods on these objects can refer to their instance > variables (and to methd args, and to globals and constants). > > Some references are optimized and encoded differently. > > Fixnums are encoded as 2's complement bit strings (for example). > Thus, '0000' is an encoded _reference_ to the fixnum '0'. > And '0001' is an encoded _reference_ to the fixnum '1'. > Such encodings also encode a set of 'instance variables' that those objects > would have explicitly stored had they been represented on the heap like > normal objects. For example, the encoding of Fixnum '1' implicitly encodes > references to its adjacent fixnums '0' and '2'. The number '0' existed well > before the bit pattern '0001' ever appeared in your Ruby program. > > Of course, methods on such objects need access to these 'instance > variables', so the methods are also optimized so they can simply work with > the encoded reference (rather than with the object itself), and again > guarantee to return (possibly encoded) references to objects. > > Fixnum# + (other_fixnum) > return a (encoded, optimized) reference to another fixnum > e.g. '0001' + '0001' => '0010' > > The discussion of Fixnums are 'immutable' is right in spirit, but in detail > bears closer inspection. Certain 'encoded' instance variables of Fixnums are > frozen. Specifically, their relationships to all other fixnums dictated by > the laws of math. i.e. these encoded instance variables are automaticaly > 'frozen' (there was a long earlier thread on this topic). After all, you > would not want 2+1 to change from 3 to 73 in the middle of your program. > > However, Fixnums can certainly have other mutable 'instance variables'; we > just have to handle the internal implementation differently because the > objects themselves are not heap allocated, so we need some other means to > get to these 'inst-vars'. > class Fixnum > @@foos = {} > def foo; return @@foos[self]; end > def foo=(x); @@foos[self]=x; end > end > > irb(main):028:0> 1 > => 1 > irb(main):029:0> 1.foo > => nil > irb(main):030:0> 1.foo= 5 > => 5 > irb(main):031:0> 1.foo > => 5 > > Whatver works for you ... Although this works I'd rather not have this kind of instance variables for fixnums because for me fixnums are atoms (i.e. building blocks of the language) without internal structure (ok, you may replace "atom" with "quark"...). Also there is the issue with garbage collection of these "instance variables"... Kind regards robert