Hi --

On Tue, 2 Sep 2003, Jeff Mitchell wrote:

> Happy Holidays!
>
> It always concerned me that instance variables of a class propagate to
> its subclasses and that instance variables of a module propagate to
> classes which include it.

Looking ahead to your code: you're not actually dealing here with
instance variables of classes or modules (i.e., instance variables of
Class or Module objects), but rather with instances variables of any
old object.  That could play a role....  I wonder whether class/module
instance variables would fit the bill in some cases.

Also, it's not exactly that instance variables propagate: it's that
classes and modules define instance methods, and then position
themselves in the method lookup chain.  So the instance variables
don't really propagate, any more than the local variables used by
those methods do.  The methods stay where they are, defined as they
are, and the object comes looking for them.

> This lack of private variables caused me great unrest until I learned
> a little more ruby and then realized private variables can be
> implemented in ruby itself!
>
> What do you think?  Criticism is welcome; this one of my first
> non-hello-world ruby scripts so be nice :) And thanks to the irc folks
> who patiently answered my questions.

You've unleashed... a monster! :-)  Actually I think it's an
interesting experiment, but I don't think it's really useable, for
reasons I'll try to explain.

On the method definition end, you're redefining the very concept of
"instance variable"; meaning, instead of having it be per instance,
you're making it per instance per module, which is categorically
different from per instance.

For example, in your code:

> puts "A's @x is #{c.a_x}"
> puts "B's @x is #{c.b_x}"
> # => A's @x is 11
> # => B's @x is 22

the concept of "A's @x" doesn't really make sense.  It's c's @x, c
being the instance whose instance variable @x is.

It may sound simple-minded, but I'd tend to say: if, in your method
definitions, you need to keep track of two bits of state information
for your object, just use two different instance variables.

On the object end -- method calls, as in your examples -- there's no
knowledge of the splitting up of @x, but there's no advantage to it
either.  Objects can do these kinds of things already, using multiple
instance variables (or whatever).

There's also the matter of assigning this much importance to the
question of where (which class or module) a method was defined in.  It
shouldn't be this important, because it can (or should be able to)
change without users of the object knowing or caring.  Once you start
scoping these variables by where you defined their methods, I think
reorganizing your modules and classes would be incredibly hard or even
impossible.

What sorts of problems are you addressing here?  It would be
interesting to see and play around with an example or particular
case.


David

-- 
David Alan Black
home: dblack / superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav