使用TclOO创建对象创建对象

时间:2014-10-24 11:24:45

标签: tcl

我正在调查TclOO,发现我们可以使用createnew来创建对象。 使用create我们可以提供自定义名称,而使用new时,它是由计算机生成的。

#!/bin/bash
#\
exec tclsh8.6 $0 $@

::oo::class create calc {
        method add { a b } {
                return [ expr {$a+$b} ]
        }
}

calc create c;
set t [ calc new ]

# Both serves the same purpose here
puts [ c add 3 4 ] 
puts [ $t  add 1 2 ] 

只是编译器为开发人员提供的对象命名方便吗?另外,我应该选择new而不是create的情况呢?

1 个答案:

答案 0 :(得分:4)

newcreate之间的唯一区别是完全create允许您提供要使用的名称,而new会让您重新认识一个给你。某些类型的对象(特别是类)隐藏了它们的new方法,因此强烈建议你只创建命名实例 - 考虑到人们如何使用类,这在实践中很有意义 - 但它只是隐藏而你可以如果你想要覆盖:

oo::define oo::class {
    export new
}

当您不关心名称时使用new,只是希望它与其他所有名称不同。这是基本的经验法则。

单身

使用create创建其他OO系统可能使用单例的实例也是完美的。比给他们一个你控制的好名字更独特的是。

寿命管理

我知道的主要场景,否则使用create更有用的是当你想要将对象的生命周期限制到另一个对象时。在这种情况下,在另一个上下文中创建对象会将对象句柄放在容器的命名空间中,并在删除容器时自动触发删除:

oo::class create InsideThing {
    constructor {} {
        puts "Made a [self] that is an InsideThing"
    }
    destructor {
        puts "Deleted a [self] that is an InsideThing"
    }
}
oo::class create Container {
    constructor {} {
        puts "Created a [self] that is a Container"
        InsideThing create inner1
        InsideThing create inner2
    }
    destructor {
        puts "Deleted a [self] that is a Container"
    }
}

set c [Container new]
puts "Do stuff..."
$c destroy

如果你运行该代码,你会得到这个:

Created a ::oo::Obj13 that is a Container
Made a ::oo::Obj13::inner1 that is an InsideThing
Made a ::oo::Obj13::inner2 that is an InsideThing
Do stuff...
Deleted a ::oo::Obj13 that is a Container
Deleted a ::oo::Obj13::inner1 that is an InsideThing
Deleted a ::oo::Obj13::inner2 that is an InsideThing

这种技术在TDBC中被广泛用于管理容器上下文中的结果集和语句(分别是语句和连接)。

Tk Megawidgets

最后,如果你使用TclOO创建Tk megawidgets,你将肯定使用create但是被覆盖的形式,因为Tk小部件必须具有不合格的名称以.开头,具有特定的具体层次结构,并强烈建议非常遵循相同的模式。因为在这种情况下名称很重要,new是错误的方法;最好从create开始。 Tk 8.6有一些支持类(没有公开描述,但在内部用于某些对话框),这使得这类事情变得更容易:tk::Megawidgettk::MegawidgetClass。有关详细信息,请查看Tk 8.6发行版中的megawidget.tcl