Tcl8.6のTclOOとRivetを少し試していますが、やりたいことができないので困っています。
.rvt
この問題は、ファイル内の次のコードで簡単に再現できます。
<?
proc dumbproc {} {
puts "this is dumbproc ([namespace current])"
}
oo::class create foo {
method bar {} {
puts "this is bar ([namespace current])"
dumbproc
}
}
set obj [foo new]
dumbproc
$obj bar
コードを単純に見ると、期待どおりに機能するはずですが、Rivetパッケージの微妙な動作と選択された特定の構成のため、実際には機能しません。
この例では、コードが名前空間.rvt
内で実行されるファイルを使用しているため、プロシージャの完全修飾名はです。名前解決アルゴリズムがメソッド内で呼び出されると、メソッド内を検索し、次に中、最後に内を検索しますが、それを見つけて次のエラーを出すことはありません。::request
dumbproc
::request::dumbproc
bar
dumbproc
::oo::Obj12
::oo
::
this is dumbproc (::request) this is bar (::oo::Obj16)
invalid command name "dumbproc"
while executing
"dumbproc"
(class "::request::foo" method "bar" line 3)
invoked from within
"$obj bar"
(in namespace eval "::request" script line 21)
invoked from within
"namespace eval request {
puts -nonewline ""
proc dumbproc {} {
puts "this is dumbproc ([namespace current])"
}
oo::class create..."
ですから、Tclはそれが行うこと、つまり機能を実行するのに正しいのです。ただし、クラスコードを作成するときは、それが使用されるコンテキストを知っている必要があるため、動作は予測できません。
<?
実際、最初のリベットマジックをドロップし、コードをtest.tcl
ファイル内に配置してインタラクティブセッションで使用すると、同じエラーが発生します。
$ tclsh
% namespace eval ::myns {source test.tcl}
this is dumbproc (::myns)
this is bar (::oo::Obj12)
invalid command name "dumbproc"
クラス作成コードの前に現在の名前空間を追加して問題を解決しようとしました
::oo::class create [namespace current]::foo { ... }
obj
次に、名前空間内にオブジェクトを作成しようとしました
::oo::class create [namespace current]::foo { ... }
namespace eval [namespace current] {set obj [[namespace current]::foo new]}
create
次に、名前空間を含む修飾名をオブジェクトに付けるために、クラスのメソッドに切り替えました。
foo create [namespace current]::obj
obj bar
しかし、すべてが失敗しました。すべての試行は、私がそれをどのように行っても、TclOOクラス内のメソッドは常にそのオブジェクトの一意の名前空間内で実行されることを示しています。私が間違っている?
私が欲しいものを手に入れる方法はありますか?TclOOはそのように機能することを意図していませんか?この場合、なぜですか?私が本当に驚いたのは、このコンテキスト依存の動作です。これが正しいかどうかはわかりませんが、完全に間違っている可能性があり、それに対する適切なケースがあります。