TclOO: экспорт / импорт пространства имен между объектами - PullRequest
0 голосов
/ 15 мая 2018

Как можно настроить передачу пространства имен между объектами 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 голосов
/ 15 мая 2018

Методы 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"
    }
}
...