"David A. Black" <dblack / wobblini.net> wrote in message

> > It's not a big deal, but a  common term would be nice.
>
> I don't think there is one that really covers it, though.  I tend to
> agree with Austin that finding such a term is a solution in search of
> a problem (I've never found it unclear to refer to instance variables
> as instance variables, array elements as array elements, hash
> key/value pairs as hash key/value pairs, etc., rather than trying to
> tie it all together) -- but also, consider what Ruby objects can do,
> and the ways they are known:
>
>     obj = Object.new
>     def obj.[](x)
>       rand(100)
>     end
>
> What is obj's state, as reflected in its indices?  Let's ask it:
>
>    irb(main):006:0> obj[1]
>    => 64
>    irb(main):007:0> obj[2]
>    => 57
>    irb(main):008:0> obj["hi"]
>    => 21

Ah. Thank you for the example.

> One might be tempted to say: well, those aren't "real" indices.

Which is, in a way, what I am about to say. But bear with me ...

You are mixing several quite different and usefully separable concerns:
1. What is the local (stored) state of an object (I've used 'slots' for
this)
2. What other non-local (stored) state can be reached via that local state
(transitive on 'slots')
3. What virtual state can be computed in read-only accessor methods via (2),
constants, etc.
4. What stored state (and hence, virtual state 3) is changed by mutators?
   What if something that looks like a read-accessor actually mutates stored
(local or non-local) state

I've been talking about (1). Freezing an instance variable, were such a
thing defined, would work on (1).

A family of closely related methods like equality (==), hash(), freeze an
_object_, ... would be about (1) and (2), with a need to behave in ways that
are mutually consistent and that are consistent with the relevant parts of
the virtual state visible via (3).

As soon as you have something like ObjectSpace that is accessible
everywhere, (3) essentially becomes the whole object graph.

Your rand() example is about (4).
rand() has to mutate some stored state somewhere (i.e. some variable,
instance, global, class, C-only, ... ). Your obj can reach and modify that
stored state via rand(). I am guessing obj.rand[10] would affect the outcome
of a subsequent obj2.rand[10] i.e. this random number state is cetainly not
local stored state (1) in obj.

So my answer would be: obj has no slots corresponding to [1], [2], ....It
does have some non-local slot (somewhere) that is both read and modified by
obj[i].

> Ruby is *fundamentally* built on dynamism and
> elastic behaviors of this kind.

I agree. But consider this example:

x = X.new
x.compute #=> 5
x.y.z.mutate 6
x.compute #=> 11
x.freeze
x.y.z.mutate 7 #=> error: can't modify frozen object
# likewise x == x1, x.hash(),  someHash[x], etc.

To even mentally understand what is going on, I (and most others, I suspect)
need some conceptual model of state that covers (1), (2), (3), and (4). At
least a mental model; though one in the code could aid testing. Some uniform
notion of "slot" is helpful for this.

> This is not to say that my object, above, contains 57 no more or less
> than the array [57] contains 57.  It contains it less -- but the point
> is that Ruby is full of ways to make things like that not matter
> and/or be very difficult to establish in the first place.

I don't know what you mean by 'contains'. In the core model I am talking
about, an object has slots; in each slot is (i.e. the value of a slot is) a
reference to some other object. I think notions such as 'contains' (quite
possibly related to my freeze example above) can be built on top of this
core model.

Your object contains some local slots, none of which refers to the object
57. More relevant, even if some of its local slots did refer to the object
57, that reference is a coincidence, and in no way related to what rand()
does.

Thanks!