"Bertram Scharpf" <lists / bertram-scharpf.de> 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).

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 ...