虽然您无法直接在oo::define
系统中创建特定于类的扩展命令,但您可以非常轻松地完成次优任务。诀窍是namespace path
仅在定义处理期间将附加命令配置到命名空间。说元类构造函数很容易做这种事情,这有点过分了:
# First, build the definition of the extensions
namespace eval ::ModuleDefineExtensions {
proc executable {program} {
# I'm not quite sure how you want to handle this, but [uplevel] and
# [info level] will reveal what you need.
puts "define executable as $program here"
}
}
# Now, the [module] metaclass
oo::class create module {
superclass oo::class
constructor {definitionScript} {
# Save the old path
set oldpath [namespace eval ::oo::define {namespace path}]
# Set the new one
namespace eval ::oo::define {namespace path ::ModuleDefineExtensions}
# Now let the superclass constructor handle this, trapping errors
catch {next $definitionScript} msg opt
# Restore the old path
namespace eval ::oo::define [list namespace path $oldpath]
# Rethrow any errors
return -options $opt $msg
}
}
您可能需要更多零碎的东西(例如,定义通用方法的合适的默认模块类超类),但这些都是常规的。
如果您使用的是 8.6,则module
定义可以更简单(这次没有注释):
oo::class create module {
superclass oo::class
constructor {definitionScript} {
set oldpath [namespace eval ::oo::define {namespace path}]
namespace eval ::oo::define {namespace path ::ModuleDefineExtensions}
try {
next $definitionScript
} finally {
namespace eval ::oo::define [list namespace path $oldpath]
}
}
}
原理上是一样的,只是使用了8.6的try/finally命令。