[英]Tcl object method called as variable
如何将对象方法作为变量执行?
oo::class create handlerTest {
method onEvent {} {
puts "onEvent method"
}
}
set testObj [handlerTest new]
#set wrapper {$testObj onEvent}
#set wrapper {$testObj::my onEvent}
#set wrapper [namespace code {$testObj onEvent}]
#set wrapper "eval testObj onEvent
#set wrapper {[eval testObj onEvent]}
$wrapper
以上所有尝试似乎都将$wrapper
作为单个命令执行,而不是带有 args 的命令。
由于我使用的是调用已定义包装器的外部库,因此我无法更改包装器的调用方式(即{*}$wrapper
)。
有没有办法做到这一点?
或者:
proc theWrapper {} [
upvar 1 testObj testObj
tailcall $testObj onEvent
}
set wrapper theWrapper
$wrapper
重写命令名称本身的唯一方法是通过未知处理程序(默认为在全局命名空间中调用为unknown
;您可能希望使用该默认值)。 执行此操作时需要小心,因为默认处理程序会执行某些代码需要提供的操作; 用rename
稍微调整一下应该可以解决问题。
# only want special treatment for some commands
set autoexpanded [list $testObj]
# save for later
rename unknown _original_unknown
proc unknown args {
global autoexpanded
# if we want to expand the first word...
if {[catch {lindex $args 0 0} cmd] == 0 && $cmd in $autoexpanded} {
# delegate to the expanded command (tailcall is perfect here)
set args [lassign $args cmd]
tailcall {*}$cmd {*}$args
} else {
# delegate to the original unknown
tailcall _original_unknown {*}$args
}
}
请注意,这不是一种快速调度机制。 它仅在唯一的其他替代方法因命令不存在而引发错误时使用(也很慢,但错误路径从未达到最佳或高度优化)。
想到的最简单的方法是为别名生成一个名称并将其放入变量中:
set testObj [handlerTest new]
set wrapper [interp alias {} wrapper[incr wrapperid] {} $testObj onEvent]
$wrapper
=> onEvent 方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.