我们如何找到我们的 tcl 环境中存在哪些包以及它们存储在哪里以及如何包含新包?

How do we find what packages exist in our tcl environment and where they are stored and how to include new packages?

我的 objective 是在我的 tcl 脚本中执行 log base 2 但它引发了一些关于 tcl 如何工作的问题。我需要做这些事情:

  1. 查找我的 tcl 环境中的可用包列表
  2. 查找程序包中可用的程序列表
  3. 查找过程的“信息”或“描述”,就像我们在 Shell
  4. 中使用 -h 或 --help 开关一样
  5. 如何将新包添加到我们的 tcl 环境中? Python(我们使用 pip 的地方)是否有为 tcl 下载的软件包?

现在我尝试自己执行一些命令,跟踪如下:

% info log
error: unknown or ambiguous subcommand "log": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars
    while executing
"info log"
% log(2.71)
error: invalid command name "log(2.71)"
    while executing
"log(2.71)"
% expr log(2.71)
0.9969486348916096
% info ::tcl::mathfunc
error: unknown or ambiguous subcommand "::tcl::mathfunc": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars
    while executing
"info ::tcl::mathfunc"
% info ::tcl::mathfunc::log
error: unknown or ambiguous subcommand "::tcl::mathfunc::log": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars
    while executing
"info ::tcl::mathfunc::log"
% expr ::tcl::mathfunc::log(2.71)
error: missing operand at _@_
in expression "_@_::tcl::mathfunc::log(2..."
    (parsing expression "::tcl::mathfunc::log(2...")
    invoked from within
"expr ::tcl::mathfunc::log(2.71)"
% info 
error: wrong # args: should be "info subcommand ?arg ...?"
    while executing
"info "
% info library
C:/intelFPGA/18.1/quartus/bin64/tcl8.6
% package names
systemconsole zlib TclOO tcl::tommath Tcl
% ::tcl::mathfunc::rand
0.6648586465347831
% info ::tcl::mathfunc::rand
error: unknown or ambiguous subcommand "::tcl::mathfunc::rand": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars
    while executing
"info ::tcl::mathfunc::rand"

关于此跟踪,让我感到困惑的是:

  1. 执行“包名称”returns“systemconsole zlib TclOO tcl::tommath Tcl”,这不包括::tcl::mathfunc。这是为什么?这个列表太小了!
  2. 为什么 log(2.71) return“无效命令名称”错误但 expr log(2.71) 有效?
  3. 为什么 expr::tcl::mathfunc::log(2.71) 失败但 ::tcl::mathfunc::rand 有效?两者不都是 mathfunc 包的一部分吗?

寻找包裹

  1. Tcl 会等待构建包列表,直到您请求一个它当前不知道其名称的包。 catch {package require thereisnosuchpackage} 应该 大部分 填充列表。

    但是,有一些包存储为 Tcl 模块并且永远不会进入列表。它们使用更高效的加载机制,但在格式上有所限制。 tcl::tm::path list 将给出可以找到它们的目录列表,并且包名称和版本从中构建到一个文件中。

    我不喜欢没有办法整齐地获取这些模块的列表,即使只是为了维护和发现目的。

表达式中的函数

  1. expr命令重写了log(1.23)函数的调用:

    expr { log(1.23) }
    

    拨打电话:

    expr { [tcl::mathfunc::log [expr { 1.23 }]] }
    

    最终相当于:

    expr { [tcl::mathfunc::log 1.23] }
    

    这实际上等于:

    tcl::mathfunc::log 1.23
    

    (这里的“虚拟”是真的,因为日志函数returns是一个浮点数。与自定义函数有一些细微的技术差异。)

  2. 注意上面的调用中括号没有了; 它们只是表达式的语法。从技术上讲,表达式是嵌入在 Tcl 中的自己的小语言(并且反过来嵌入了 Tcl)。

    rand 的重写最终删除了括号,因为它不带任何参数。