Tcl中类实例的共享变量

时间:2017-01-18 15:51:51

标签: oop static tcl

在Ruby中,可以为同一个类的实例(静态)共享一个变量。即,所有人都看到相同的价值,并且可以改变它。它可以节省内存,并可以带来其他好处。这也可以通过Perl,C ++等实现。如何在版本8.6的Tcl OO中实现相同的功能?
谢谢。

2 个答案:

答案 0 :(得分:2)

由于TclOO旨在成为骨头,因此需要一些脚本来实现结果。 tcllib中的oo::util包提供了必要的代码。

答案 1 :(得分:1)

使类范围的变量适当地显示给实例有三个步骤。

步骤1:在类中设置一个值:

如果你能够处理一个未设置的变量,你不需要做太多。有些代码可以,有些则不能。

oo::class create Example {
    self variable foo
    self method init {} {
        set foo 123
    }
}
Example init

步骤2:为将访问变量

的实例定义一些方法

我们的例子就是一个。请注意,我必须在这里说variable;它与self variable的范围不同。 (实例与类)

oo::define Example {
    variable foo
    method bar {} {
        incr foo
        puts "foo is $foo"
    }
}

步骤3:将实例变量绑定到构造函数

中的类变量

这是一个棘手的问题。

oo::define Example {
    constructor {} {
        # Get the class's own private object namespace, where it keeps its own variables
        set ns [info object namespace [self class]]
        # Link the instance variable to the class variable; 'my eval' uses right context
        # You can rename the variable here; see 'namespace upvar' docs for details
        my eval [list namespace upvar $ns foo foo]
    }
}

有了这三个,我们可以做一些实例并尝试一下:

set e1 [Example new]
set e2 [Example new]
$e1 bar; # ==> foo is 124
$e1 bar; # ==> foo is 125
$e2 bar; # ==> foo is 126
$e2 bar; # ==> foo is 127

请注意,这可以通过 实例'命名空间 中的变量 连接到单个变量 类的命名空间 。此链接在此处使用namespace upvar完成,这是您之前可能没有使用过的命令。它也可以使用upvar命令完成,尽管这样做的效率较低。

便于学习的合并脚本

它看起来有点不同,但它做同样的事情:

oo::class create Example {
    self {
        variable foo
        method init {} {
            set foo 123
        }
    }
    variable foo
    constructor {} {
        set ns [info object namespace [self class]]
        my eval [list namespace upvar $ns foo foo]
    }
    method bar {} {
        incr foo
        puts "foo is $foo"
    }
}
Example init
set e1 [Example new]
set e2 [Example new]
$e1 bar; # ==> foo is 124
$e1 bar; # ==> foo is 125
$e2 bar; # ==> foo is 126
$e2 bar; # ==> foo is 127