TclOO:my 和 self 有什么区别?

TclOO : What is the difference between my and self?

文档可能解释得很好,但在我的案例中我看不出这 2 个命令之间的区别:

method dir {} {
    puts "method dir..."

}

method pseudomethod {} {
    set vardir [my dir]
    set vardir [[self] dir]
}

我能看到的唯一区别是使用 [self] 我可以将它作为过程中的参数传递,而不是使用 my
在我的案例中最好的解决方案是什么?
两种解决方案具有相同的性能?

我不确定它们是如何实现的,但您想要使用 my 的原因之一是访问非导出(私有)方法。演示:

oo::class create Foo {
    method PrivateMethod {} {puts "this is PrivateMethod"}
    method publicMethod {} {puts "this is publicMethod"}
    method test {} {
        my publicMethod
        my PrivateMethod
        [self] publicMethod
        [self] PrivateMethod
    }
}

然后:

% Foo create foo
::foo
% foo test
this is publicMethod
this is PrivateMethod
this is publicMethod
unknown method "PrivateMethod": must be destroy, publicMethod or test

my是对象调用其方法的机制。
self 是自省当前方法调用方式的机制。

花一些时间阅读 my and self 手册页。

self 命令(没有额外参数)等同于 self object,其中 returns 当前 public 名称正在执行该方法的对象(您可以 rename 对象)。 self 命令总体上提供了对“运行time”状态位的访问。

my命令实际上是对象的内部名称;它是在每个对象的实例命名空间中创建的。与 public 名称不同,您可以通过 my 调用所有导出和未导出的方法。这使得它既可用于直接调用内部方法,也可用于设置内部方法的回调(设置回调时需要 namespace whichnamespace code 之类的东西)。

与public名称不同,您可以删除内部名称命令而不会自动销毁对象。如果你这样做,它可能会破坏代码(很可能是你的方法),但基本系统允许你这样做。


旁白:Tcl 8.7 包括这个帮助程序(它也适用于 8.6),用于在方法中创建回调脚本(有趣的名称意味着它会自动映射到您的方法中,如 callback):

proc ::oo::Helpers::callback {method args} {
    list [uplevel 1 {::namespace which my}] $method {*}$args
}

在这种情况下,如果回调被导出,您可以改为这样做:

proc ::oo::Helpers::callback {method args} {
    list [uplevel 1 self] $method {*}$args
}

但这更容易受到 rename 问题的影响。 (在所有情况下,uplevel 1 是因为我们想在调用上下文中 运行 一些名称解析代码,而不是在过程本身的范围内。)