TCL regsub для переменной?

Я устанавливаю макросы, Set и Say. Определено в процедурах.

proc Set {key value args} {
    set ::$key $value
            set "::key2" "$key"
}

proc Say {key} {
puts $key
}

proc Say2 {key} {
set key3 [regsub "\%" $key "\$"]
puts $key3
eval puts $key3
}

Что позволяет мне выполнить следующее:

Set "test" "this should display this test text"
Say $key2 ;#should display the key "test" which is what we just set
Say $test ;#presents the value of the key test

Выход

% Set "test" "this should display this test text"
test
% Say $key2 ;#should display the key "test" which is what we just set
test
% Say $test ;#presents the value of the key test
this should display this test text

Итак, теперь допустим, что я хочу переназначить переменную $ на%

Set "mouse" "squeak" ;#set key mouse with value string of "squeak"
Say $mouse ;#displays the value as set above correctly
Say2 %mouse ;#start using our own characters to represent variables - switch the % for a $ and then output

Однако я получаю при использовании Eval,

 can't read "mouse": no such variable

Выход

% Set "mouse" "squeak" ;#set key mouse with value string of "squeak"
mouse
% Say $mouse ;#displays the value as set above correctly
squeak
% Say2 %mouse ;#start using our own characters to represent variables
$mouse
can't read "mouse": no such variable

Я нахожу это странным, потому что мы установили его выше, мы можем вспомнить значение, используя стандартный $, и я могу доказать, что regsub в Say2 работает так, как он должен заменить% на $.

% mouse становится $mouse, которая является допустимой переменной. Eval $mouse output без такой переменной

Я что-то пропустил?

Спасибо

1 ответ

Решение

Проблема с proc:

proc Say2 {key} {
    set key3 [regsub {%} $key {$}]
    puts $key3
    eval puts $key3 ;# here
}

$mouse не существует в этом proc, Он не был передан в качестве параметра и не был создан с set, Однако существует в глобальном пространстве имен. Одним из способов достижения этого является использование uplevel в этом случае:

proc Say2 {key} {
    set key3 [regsub {%} $key {$}]
    puts $key3
    uplevel puts $key3
}

Другой вариант, который я часто использую, это upvar чтобы привести переменную внутрь (хотя в этом случае мы не хотим $ больше):

proc Say2 {key} {
    set key3 [regsub {%} $key {}]
    puts $key3
    upvar $key3 var
    puts $var
}

PS: я также пошел дальше и удалил некоторые обратные слеши, так как они не нужны в этом сценарии.

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