tcl

Making a derived class variable accessible without "my variable ..."


are there any possibilities making _foo accessible in class C without having to write my variable _foo?

Caveat: I don't want to make all variables (e.g. _bee) visible, only some specific variables like _foo.

Also found this post, but I think it is doing it for all class and variables because it modifies the way classes are created in a global context. TclOO Variable Scope with Inheritance/superclass

Maybe there is something I can do in the constructor of class A to achieve this.

thx!

Class A:

oo::class create A {
    variable _foo
    variable _bee
}
oo::define A constructor args {
    set _foo 1
    set _bee 2
}
oo::define A method get_foo args {
    return $_foo
}

Class B:

oo::class create B {
    superclass A
}
oo::define B constructor args {
    next {*}$args
}
oo::define B method get_foo args {
    my variable _foo
    return $_foo
}

Class C:

oo::class create C {
    superclass A
}
oo::define C constructor args {
    next {*}$args
}
oo::define C method get_foo args {
    return $_foo
}

Solution

  • You need to declare at the class level that you're making the variable visible to that class's methods by default; that declaration doesn't propagate to subclasses (I tried it the other way at first, and that sucked more in real examples based on doing megawidget classes). The way this is envisaged to work is like this:

    oo::class create A {
        variable _foo _bee
        constructor args {
            set _foo 1
            set _bee 2
        }
        method get_foo args {
            return $_foo
        }
    }
    
    oo::class create C {
        superclass A
        variable _foo
        constructor args {
            next {*}$args
        }
        method get_foo args {
            return $_foo
        }
    }
    

    The non-inherited nature means that the in-scope variables are more opt-in than in many other object systems. They're still there in the object, but they're not forced on the subclasses.

    In 9.0, you also have private variable declarations, which do name mangling for you behind the scenes.