После импорта процов из пространства имен с параметром force, прокси в глобальном пространстве имен используются auto_load в определенных условиях - PullRequest
0 голосов
/ 27 февраля 2019

Я работал над проектом, где сценарии написаны для одного оборудования (скажем, типа A), и у меня есть много проков, специально предназначенных для этого конкретного оборудования.И теперь, когда я пытаюсь использовать те же сценарии для нового оборудования (скажем, типа B), я подумал о следующем подходе: 1. Переопределите все процессы в новом файле библиотеки в новом пространстве имен.2. При запуске основного скрипта проверьте тип оборудования.а.Если тип А ничего не делать.Используются процы из глобального пространства имен (наследие) b.Если тип B делает «import -force пространства имен» из библиотеки в глобальное пространство имен.

Проблема здесь в том, что проект использует auto_load, поэтому при импорте из новой библиотеки устаревшие процессы не находятся вконтекст еще.Когда вызывается процесс, общий для обоих аппаратных средств, и если файл, содержащий этот процесс, также имеет другой процесс, который был переопределен для типа B, то этот процесс перезаписывается глобальным процессом пространства имен (устаревший тип A), даже если я сделалпринудительный импорт ранее.

Если формулировки трудно следовать, обратитесь к приведенному ниже образцу кода и его выводу.Если фиктивный процесс перемещен из TypeB.tcl в новый файл, проблема не возникает.

[wizard @ work]$ cat main.tcl
#!/usr/bin/tclsh
auto_mkindex ./
set auto_path "$auto_path ./"
namespace import -force TypeB::*
print_name
dummy
print_name

[wizard @ work]$ cat TypeA.tcl

proc print_name { } {
   puts "From the TypeA"
}
proc dummy {} {
   puts "Do nothing"
}

[wizard @ work]$ cat TypeB.tcl
namespace eval TypeB {
   namespace export *

   proc print_name {} {
      puts "From the TypeB"
   }

}


[wizard @ work]$ ./main.tcl
From the TypeB
Do nothing
From the TypeA
[wizard @ work]$

1 Ответ

0 голосов
/ 27 февраля 2019

Посмотрите, что делает auto_mkindex: он создает файл tclIndex, который содержит

set auto_index(print_name) [list source [file join $dir TypeA.tcl]]
set auto_index(dummy) [list source [file join $dir TypeA.tcl]]
set auto_index(::TypeB::print_name) [list source [file join $dir TypeB.tcl]]

Когда вы namespace import TypeB::*, tcl выполняет source [file join $dir TypeB.tcl], и процесс print_name вытягивается вглобальное пространство имен.

Что происходит, когда вы звоните dummy?this: source [file join $dir TypeA.tcl] - тянет процесс dummy в глобальное пространство имен.Но в то же время, print_name proc является переопределенным .

На данный момент, вы все равно можете позвонить TypeB::print_name

Вам придется сделать одиниз:

  • реструктурировать ваш код,
  • повторно выполнить namespace import TypeB::*, или
  • быть очень осторожным, например, в порядке, в котором вы вызываете вещипозвонив dummy сначала .
...