Hello --

On Wed, 3 Jul 2002, Gray, Jeff wrote:

> This question probably has more to do with the fundamentals of OOP than Ruby
> specifically, but I'm looking for an explanation of why the behavior of
> class variables in inherited classes is the way it is.  Consider:
>
> ---
> class Box
>   # @@stuff = {:e => 1}   # intentionally commented out
>   def Box.add(k, v)
>     @@stuff[k] = v
>   end

[...]

> Crate.add(:d, 4)

Don't you get an "uninitialized class variable" error at that point
(if line 2 is commented out)?

> So when a class variable is defined in a parent class, all inherited classes
> see the same object.  More specifically, the most recent definition of that
> class variable is used, even if it occurred in a subclass.  Yet when a class
> variable is not initialized in the parent class, the variable points to
> different objects in each class.  This is sensible, but it feels like there
> is lacking a "have your cake and eat it too" mechanism that allows for
> inherited classes to override/redefine class variables without affecting the
> ancestor and sibling classes.
>
> So what are the guiding principles of inheritance that account for this
> behavior?

I think you're right that class variables are essentially
per-hierarchy (rather than per class) objects.  Also that if you
define them first in a subclass, this doesn't propagate upward (which
Matz referred to in ruby-talk:19774 as "an error that Ruby does not
detect yet", so I would treat it as deprecated behavior).

If you want real per-class variables, you can create instance
variables for your classes:

  class A
    @var = "I am A's instance variable."
    def A.speak
      puts @var
    end
  end

  class B < A
    puts @var   # nil, because @var is an instance variable of
                # a different object (namely A)
  end


This is different from a class variable, but possibly useful in that
it does provide per-class behavior.


David

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