TclOO:跨对象命名空间导出/导入

时间:2018-05-15 12:12:55

标签: namespaces tcl

如何设置TclOO跨对象命名空间传输?

具体来说,在下面的例子中:

  • runner对象需要将其方法命名空间导出为命令
  • invoker对象需要导入runner命名空间以用作DSL

以下Tcl 8.6中的示例:

#!/usr/bin/env tclsh
namespace eval ::runner {
    ::oo::class create Runner {
        constructor {} {
            namespace export RUN
            puts "runner.export: [namespace export]"
        }
        method RUN {} {
            puts "runner.RUN"
        }
    }
}
namespace eval ::invoker {
    ::oo::class create Invoker {
        variable runner
        constructor {} {
            set runner [::runner::Runner new]
            set runnerNS [info object namespace $runner]
            namespace import ${runnerNS}::*
            puts "invoker.import: [namespace import]"
        }
        method process {} {
            puts "invoker.process: [RUN]"
        }
    }
}
set invoker [::invoker::Invoker new]
$invoker process

产生此错误:

runner.export: RUN
invoker.import: 
invalid command name "RUN"
    while executing
"RUN"
    (class "::invoker::Invoker" method "process" line 2)

1 个答案:

答案 0 :(得分:1)

TclOO方法不是命令。 (从技术上讲,这是因为它们具有不同的C签名。)为了使其工作,您需要在对象中创建一个额外的命令,作为该方法的委托;有效地执行此操作的诀窍是使用tailcall my来执行调度。

oo::class create Runner {
    constructor {} {
        proc RUN args {tailcall my RUN {*}$args}
        namespace export RUN
        puts "runner.export: [namespace export]"
    }
    method RUN {} {
        puts "runner.RUN"
    }
}