Hal E. Fulton wrote:

>Well, I think that in Java/C++ they're inherited but not shared.
>In Ruby they're shared.
>
>Of course, there's an ugly trick that gets around this... can anyone
>guess it? David showed it to me once.
>

Are you referring to the "class << self.class" trick (alluded to by Matz 
and others elsewhere in the thread)?

If you think it's ugly, you can always wrap methods around it to make it 
look more like normal access, or
at least more normal by Java standards. :)

Code below.

- Dan

class Module
    # Java style class variables
    # if class Foo defines a static variable, all subclasses can see it
    # but it can be overrided by re-declaring, so to speak.
    #
    # static_var :foo  (re-)declares a static class variable
    # static variable are modifiable in subclasses unless redeclared, as 
they
    # are in Java
    def static_var(*args)
        static_var_writer *args
        static_var_reader *args
    end
   
    def static_var_reader(*args)
        args.each do |symbol|
            eval <<-EOF
                def #{name}.#{symbol.id2name}
                    class << #{name}
                        @#{symbol.id2name}
                    end
                end
            EOF
        end
    end
   
    def static_var_writer(*args)
        args.each do |symbol|
            eval <<-EOF
                def #{name}.#{symbol.id2name}=(value)
                    class << #{name}
                        proc do |e| @#{symbol.id2name} = e end
                    end.call value
                end
            EOF
        end
    end
   
    # More restrictive class instance variables
    # These variables are shared by all instances of the class, but
    # subclasses cannot see or modify them through the accessors. The
    # accessors will still exist, but they will deal with the subclass'
    # own class instance variable, and not interfere with that of the
    # superclass
    def cinst_var(*args)
        cinst_var_writer *args
        cinst_var_reader *args
    end
   
    def cinst_var_reader(*args)
        args.each do |symbol|
            class_eval <<-EOF
                def self.#{symbol.id2name}
                    class << self
                        @#{symbol.id2name}
                    end
                end
            EOF
        end
    end
   
    def cinst_var_writer(*args)
        args.each do |symbol|
            class_eval <<-EOF
                def self.#{symbol.id2name}=(value)
                    class << self
                        proc do |e| @#{symbol.id2name} = e end
                    end.call value
                end
            EOF
        end
    end
end

class Foo
    static_var :var
    cinst_var :var2
end

class Bar < Foo
end

class Baz < Foo
    static_var :var
end

Foo.var = 5

p Foo.var
p Bar.var
p Baz.var

Bar.var = 6

p Foo.var
p Bar.var
p Baz.var

Baz.var = 7

p Foo.var
p Bar.var
p Baz.var


Foo.var2 = 8

p Foo.var2
p Bar.var2
p Baz.var2

Bar.var2 = 9

p Foo.var2
p Bar.var2
p Baz.var2

Baz.var2 = 10

p Foo.var2
p Bar.var2
p Baz.var2