如何在TclOO对象的构造函数中声明可调数量的变量,这些变量在其他方法中是可见的?

时间:2014-09-01 16:09:58

标签: tcl scope superclass

这有点类似于这个问题TclOO Variable Scope with Inheritance/superclass, 但我想为我的类中的方法提供一些变量,以及哪些变量在运行时动态确定。 伪代码:

oo::class create myClass {
    constructor {registryObject} {
        foreach variable [$registryObject getVariables] {
            <make $variable visible to all methods>
        }
    method useVariable{} {
        <do something with previously declared variable>
    }
}

有没有办法实现这个没有另一层间接?问题是registryObject给了我一些可变数量的对其他对象的引用,我希望在派生类中可以访问它们。与上面引用的问题一样,这里的要点是派生类的代码简洁。如果需要的话,我愿意在超类中使用肮脏而复杂的黑客。

1 个答案:

答案 0 :(得分:0)

真的很难完全按照你的要求去做。

TclOO中使用的variable类声明调整Tcl如何解析在同一个类中声明的(正常类定义的)方法中的变量。它不会影响超类,子类或实例定义的方法(如果需要,它们应该使用自己的variable声明)。变量本身虽然可见 - 与实例关联的所有变量都是当前命名空间中的变量,而对象正在执行(这是特定于实例的) - 它们只需要显式引入。

如果使用对注册表对象查询的响应来动态创建实例方法,则可以这样做:

constructor {registryObject} {
    foreach variable [$registryObject getVariables] {
        oo::objdefine [self] variable $variable
    }
    oo::objdefine [self] method foo {...} {
        # This method *will* have automatic access
    }
}

是的,该方法是在构造函数内创建的(并且在类上创建方法没有多大意义)。不,大多数其他对象系统都没有实例方法。可以认为它有点像为每个实例提供自己特殊的小类。 (那不是发生了什么,但它并不太遥远。)

你要求做什么

如果你要为类的所有实例创建方法,那么在创建类(无聊,常规!)或创建类的第一个实例期间这样做是有意义的,假设注册表做了明智的事情,并为该类的所有实例提供相同的答案。如果是这样的话,你就可以做到。覆盖createnew方法可能是最简单的方法:

oo::class create myClass {
    self method create {name registryObject} {
        foreach var [$registryObject getVariables] {
            oo::define [self] variable $var
        }
        next $name $registryObject
    }
    self method new {registryObject} {
        foreach var [$registryObject getVariables] {
            oo::define [self] variable $var
        }
        next $registryObject
    }

    constructor ...
    method ...
}

这样做有点慢,因为每个对象创建都会触发重新编译很多东西,但它应该有用。

或者你可以在构造函数中执行它;我认为它不那么优雅,但你可能不同意:

constructor {registryObject} {
    oo::define [self class] variable {*}[$registryObject getVariables]
}

我认为这两个选项都不是很好的方法 ,我建议在创建类时进行注册表查找。或者使方法不依赖于variable机制,而是使用my variable(非常类似于global但是例如变量)来访问他们需要的变量。

如果我能更准确地弄清楚大局是什么,我可以帮助你更好......