Как прочитать имя переменной, в которой хранится значение

Пример программы TCL:

proc fun { x } {
    puts "$$x = $x"
}
set a 10
fun $a

В этой вышеупомянутой программе, которая печатает вывод как $10 = 10 Но я бы хотел получить a = 10 имеет выход. Переменная, которая передает значения, должна быть прочитана, а также соответствующие значения. Есть ли способ прочитать имя переменной.

4 ответа

proc fun name {
    upvar 1 $name var
    puts "$name = $var"
}
set a 10
fun a

Команда upvar берет имя и создает псевдоним переменной с этим именем.

Документация: проц, ставит, устанавливает, упвар

Если у вас есть поддерживаемая в настоящее время версия Tcl (8.5 или 8.6), вы можете использовать info frame -1 узнать некоторую информацию о звонящем. В нем есть всякая информация, но мы можем сделать разумное приближение следующим образом:

proc fun { x } {
    set call [dict get [info frame -1] cmd]
    puts "[lindex $call 1] = $x"
}

set a 10
fun $a
# ==> $a = 10
fun $a$a
# ==> $a$a = 1010

Теперь использование lindex там строго неправильно; это код Tcl, а не список (и вы увидите разницу, если будете использовать сложную подстановку команд). Но если вы когда-либо используете довольно простое слово, оно работает достаточно хорошо.

% set x a
a
% set a 10
10
% eval puts $x=$$x
a=10
% puts "$x = [subst $$x]"
a = 10
% puts "$x = [set $x]"
a = 10
%

Если вы передаете переменную в процедуру, вы должны полагаться на upvar,

Очевидно, есть другой способ, который я нашел на других страницах форума.

upvar работает быстрее, если доступ/использование переменной более одного раза, в противном случае, если используется только один раз и это глобальная переменная "[set ::[имя набора]]" может быть лучше.

Приведенная ниже процедура использует глобальное пространство имен для проверки его существования и устанавливает значение по умолчанию, если нет. Печатает текущее значение.

      proc setvardefault {name value} {
  # if global var name does not exist set it to value
  if {![info exists ::[set name] ]} { set ::[set name] $value }
  # print the current value of global var name
  puts "# INFOCHECK $name : [set ::[set name]]"
  #upvar 1 $name var
  #puts "# INFOCHECK $name : $var"
}

Для печатной части нужны только путы.

Другие вопросы по тегам