tcl - info vars 命令在 proc 内无法正常工作
问题描述
我正在尝试使用 TCL 进行一些变量自动完成(这适用于 jimtcl)
我在 tclsh 和 jimsh 中都尝试了以下顺序:
% set VAR1 1
1
% set VAR2 2
2
% info vars
.... tcl_pkgPath VAR1 tcl_patchLevel VAR2 argc ...
% set pattern \$V*
$V*
% set vars_pattern [string range $pattern 1 end]
V*
% puts [lsort [info vars $vars_pattern]]
VAR1 VAR2
%
这可以。
但是一旦我把它变成一个过程
% proc autocomplete_helper pattern {
# check for variables auto-completion
puts "pattern '$pattern'"
if {[regexp {\$\S+$} $pattern match]} {
set vars_pattern [string range $match 1 end]
puts "pattern '$vars_pattern'"
return [lsort [info vars $vars_pattern]]
}
puts "other stuff to do"
}
% autocomplete_helper zerazer
pattern 'zerazer'
other stuff to do
% autocomplete_helper \$V*
pattern '$V*'
pattern 'V*
%
你知道为什么这不起作用吗?
解决方案
该info vars
命令对其当前上下文(很明显;它返回当前可见的变量)敏感,并将事物移动到过程中会改变它。对此的正确解决方法是使用uplevel
在不同的上下文中运行命令,或者uplevel 1
在调用者的上下文uplevel #0
中运行,或者在全局上下文(堆栈顶部的上下文)中运行。
在这种情况下,我们需要小心一点,因为模式中可能包含元字符(这很奇怪但合法)并且uplevel
是eval
-like; 该list
命令将确保我们有一个格式正确的命令。将此行放入您的程序中显而易见的点(其他所有内容均未更改)
# The double quotes around #0 are to fool the highlighter used on Stack Overflow
return [lsort [uplevel "#0" [list info vars $vars_pattern]]]
有了它,我可以这样做:
% autocomplete_helper {$e*}
pattern '$e*'
pattern 'e*'
env errorCode errorInfo
这对我来说是正确的。
推荐阅读
- gitlab - 合并后特定文件更改时从 gitlab 发送邮件
- c# - 如何修复此错误“Microsoft.Extensions.Azure:无法加载文件或程序集'System.Diagnostics.Tracing,版本 = 5.0.0.0”
- c - 退格逃逸可以取消换行符吗?
- ios - UITableView 单元格重叠搜索栏视图设置为 NavigationBar 的 searchController
- sql-server - 如果在触发器中更新了两列之一,如何插入另一个表?
- javascript - 即使我不使用道具,React 道具也在更新
- google-analytics-api - Google Analytics API - 如何在没有管理员身份的情况下获取访问令牌
- swift - 在预览时增加函数中的变量会产生错误(swiftui)
- java - 有没有办法获取一个类的所有成员类并循环它们以执行方法?
- python-3.x - 使用python将excel工作表作为对象插入到excel工作表中