2016-03-07 4 views
0

У меня есть переменная пространства имен, которое определяется, как показано ниже:Понимание использования Tcl переменного пространства имен

namespace eval ::SMB::{ 
     variable SmbInfo 
     ------ 
     ------ 

    proc ::SMB::SmbCreate {name dutport} { 
     variable SmbInfo 
     global DutPorts DutPort_2 DutPorts_3 smb 

     ------ 
     ------ 
     if{"" != [info command SMB::$name]} { 
      return -code error "command name \"$name\" already exists" 
     } 
     set SmbInfo($name -DutPort) $dutport 

Я новичок в Tcl и пытаюсь понять выше кусок кода. Несколько вопросов, пожалуйста, поправьте меня, если я неправ в любой момент:

  1. Переменная SmbInfo определяется на первое место в пространстве имен становится переопределяется одной объявленной в процедуре SmbCreate. Я не могу понять, какова цель линии:

     set SmbInfo($name -DutPort) $dutport 
    

    Я могу видеть, что «DutPorts» определяется как глобальная, но я не мог найти «DutPort». Я еще не выполнил код. Это может быть ошибка?

  2. Is ($ name - DutPort) создает индекс массива для переменной SmbInfo, а значение $ dutport устанавливается на эту конкретную переменную массива?

  3. У меня есть аналогичные структуры кода в файле, как показано ниже

    set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)] 
    

    Где BuildMac1 процедура. Немного объяснение вышеприведенного кода также может сделать это понятным.

Если что-то упущено, чтобы отправить сообщение в вопрос, пожалуйста, укажите мне, я отредактирую свой вопрос. Спасибо заранее.

ответ

1
  1. Второе объявление не переопределяет, в обоих случаях это одна и та же переменная.
  2. Эта команда является синтаксической ошибкой из-за пробела после $ name. Цель состоит в том, чтобы присвоить значение $ dutport члену SmbInfo, который имеет имя «$ name -DutPort» (где $ name заменяется значением переменной).
  3. Аналогичное назначение, но здесь значение получается из результата команды.

В коде есть несколько синтаксических ошибок, слишком много или слишком мало пробелов здесь и там. Кажется маловероятным, что этот код когда-либо выполнялся.

Цель команды smb :: SmbCreate состоит в том, чтобы: 1) создать новую команду в пространстве имен SMB, названном первым параметром (если такая команда уже не существует) и 2) хранить метаданные в пространстве имен SmbInfo переменная, индексированная a) параметром имени и b) ключевое слово, такое как -DutPort или -SmbSetDmac.

Такой код, по сути, реализует объектно-ориентированный интерфейс ad hoc. Если проблемы с пробелами решены, они должны работать нормально.

1

У вас много синтаксических проблем, которые могут вызвать у вас много горя. Tcl очень заботится о его синтаксическом уровне, который включает в себя именно то место, где есть пробелы и новые строки, и есть ли { брекеты } и [ скобки ] как и ожидалось. Вы должны получить все правильно.

Глядя на конкретный код вы испытываете проблемы, этой линии:

set SmbInfo($name -DutPort) $dutport 

казалось бы, весьма маловероятно, так как она проходит три аргумента команды set, когда это требуется только один или два , Я предполагаю, что у вас есть команда, вы звоните, чтобы получить ключ для массива, и что, следовательно, код должен быть таким:

set SmbInfo([$name -DutPort]) $dutport 

Смотрите эти [ скобки ]? Здесь они имеют значение, поскольку они говорят: «Запустите мое содержание как маленький индекс и используйте результат». При этом выясняется, что существует вопрос, работает ли вообще $name -DutPort, но вам просто нужно руководствоваться сообщениями об ошибках. Tcl обычно дает очень хорошие сообщения об ошибках, хотя иногда вам приходится думать о том, почему код попал в состояние, когда он передает это сообщение, чтобы выяснить, какова фактическая проблема. Вы знаете, обычные отладки ...

Я бы ожидать подобные проблемы с:

set SmbInfo($name - SmbSetDmac) [BuildMac1 $SmbInfo($from_name-DutPort)] 

и предположили бы, что это на самом деле должно быть:

set SmbInfo([$name -SmbSetDmac]) [BuildMac1 $SmbInfo([$from_name -DutPort])] 

Примечания снова, что я изменил пространство чтобы следовать существующему шаблону (который, как я предполагаю, является доступом к свойствам, он выглядит как OTcl или XOTcl) и добавил скобки.

Наконец, эта линия:

if{"" != [info command SMB::$name]} { 

также синтаксический неправильно, и вместо этого должна быть:

if {"" != [info command SMB::$name]} { 

, что дополнительные вопросы пространства, потому что она отделяет слово, которое является именем команды (if) от слова, которое является выражением условия. Остальная часть строки, вероятно, правильная (SMB::$name может быть подозрительной, за исключением того, что вы используете ее в , но тогда вам, вероятно, понадобится только info command $name, поскольку она уже знает о том, какое пространство имен вы работаете, и вы используете неквалифицированный имя в другом месте).

+0

Не кажется ли вам немного странным, чтобы сначала утверждать, что команда не существует, а затем быстро вызвать ее? –

Смежные вопросы