无法从用Tcl编写的应用程序中找到软件包 [英] Can't find package from application written in Tcl

查看:344
本文介绍了无法从用Tcl编写的应用程序中找到软件包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢您的评论,可以更好地理解问题.变量:

Thanks to the comments, better understand the problem a bit. The variables:

thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ echo 'puts $auto_path' | tclsh
/usr/share/tcltk/tcl8.6 /usr/share/tcltk /usr/lib /usr/local/lib/tcltk /usr/local/share/tcltk /usr/lib/tcltk/x86_64-linux-gnu /usr/lib/tcltk /usr/lib/tcltk/tcl8.6
thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ echo 'puts $tcl_pkgPath' | tclsh
/usr/local/lib/tcltk /usr/local/share/tcltk           /usr/lib/tcltk/x86_64-linux-gnu /usr/lib/tcltk /usr/share/tcltk         /usr/lib/tcltk/tcl8.6 /usr/lib
thufir@dur:~/tcl/packages$ 

代码:

thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ ll
total 16
drwxrwxr-x 2 thufir thufir 4096 May  4 02:22 ./
drwxrwxr-x 6 thufir thufir 4096 May  4 02:22 ../
-rw-rw-r-- 1 thufir thufir  215 May  4 02:21 foo.tcl
-rw-rw-r-- 1 thufir thufir 1207 May  4 02:20 tutstack.tcl
thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ cat foo.tcl 
package require tutstack 1.0

set stack [tutstack::create]
foreach num {1 2 3 4 5} { tutstack::push $stack $num }

while { ![tutstack::empty $stack] } {
    puts "[tutstack::pop $stack]"
}

tutstack::destroy $stack
thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ cat tutstack.tcl 
# Register the package
package provide tutstack 1.0
package require Tcl      8.5

# Create the namespace
namespace eval ::tutstack {
    # Export commands
    namespace export create destroy push pop peek empty

    # Set up state
    variable stack
    variable id 0
}

# Create a new stack
proc ::tutstack::create {} {
    variable stack
    variable id

    set token "stack[incr id]"
    set stack($token) [list]
    return $token
}

# Destroy a stack
proc ::tutstack::destroy {token} {
    variable stack

    unset stack($token)
}

# Push an element onto a stack
proc ::tutstack::push {token elem} {
    variable stack

    lappend stack($token) $elem
}

# Check if stack is empty
proc ::tutstack::empty {token} {
    variable stack

    set num [llength $stack($token)]
    return [expr {$num == 0}]
}

# See what is on top of the stack without removing it
proc ::tutstack::peek {token} {
    variable stack

    if {[empty $token]} {
    error "stack empty"
    }

    return [lindex $stack($token) end]
}

# Remove an element from the top of the stack
proc ::tutstack::pop {token} {
    variable stack

    set ret [peek $token]
    set stack($token) [lrange $stack($token) 0 end-1]
    return $ret
}
thufir@dur:~/tcl/packages$ 
thufir@dur:~/tcl/packages$ tclsh foo.tcl 
can't find package tutstack 1.0
    while executing
"package require tutstack 1.0"
    (file "foo.tcl" line 1)
thufir@dur:~/tcl/packages$ 

据我了解,我需要编译软件包所在位置的列表或地图.

to my understanding, I need to compile a list or map of where packages are.

推荐答案

问题是Tcl找不到包的索引文件(应称为pkgIndex.tcl).如果您已经将weather 1.0包实现为文件weather.tcl,那么您可能会希望在同一目录中有一个类似的索引文件:

The problem is that Tcl is not finding the index file (which should be called pkgIndex.tcl) for your package. If you had implemented the weather 1.0 package as a file weather.tcl, then you'd probably be looking to have an index file something like this in the same directory:

package ifneeded weather 1.0 [list source [file join $dir weather.tcl]]

表示加载weather软件包的版本1.0,运行此脚本",该脚本在运行时生成,并将$dir绑定到其中(该变量始终在软件包索引加载器的上下文中定义运行package ifneeded).

That says "to load version 1.0 of the weather package, run this script" where the script is generated at runtime and binds $dir in (which is a variable always defined in the context where package index loader runs package ifneeded).

在那里,您需要允许Tcl查找索引文件.这可以通过将该目录或其直接父目录放在Tcl全局auto_path列表中来完成.您可以在加载任何程序包之前在脚本中执行此操作(这对于具有内部程序包的应用程序非常有用),也可以通过设置TCLLIBPATH环境变量从Tcl外部对其进行初始化.请注意,该变量的值是目录的 Tcl列表,而不是像env(PATH)这样的系统路径.如果目录名称中包含反斜杠或空格,或者要在列表中包含多个元素,则这很重要.幸运的是,即使在Windows上,也可以使用/代替\并遵循通常的安装做法,并且不在名称中添加空格,从而即使在Windows上也将单个目录添加为环境变量,通常可以避免所有这些问题. .在应用程序启动期间添加路径时,它更容易:您只需使用lappend,也许是这样(非常早在您的主脚本中):

Once that's there, you need to allow Tcl to find the index file. This can be done by putting that directory or its immediate parent on the Tcl global auto_path list; either do that inside your script before you load any packages (very useful for applications that have internal packages) or you can initialise that from outside of Tcl too by setting the TCLLIBPATH environment variable. Note that the value of that variable is a Tcl list of directories, not a system path like env(PATH). This matters if you have backslashes or spaces in directory names, or if you want to have multiple elements on the list. Fortunately, you can usually avoid all of these issues in the case of adding a single directory as an environment variable, even on Windows, by using / instead of \ and by following usual installation practice and not putting a space in names. When adding a path during application launch it's easier: you just use lappend, perhaps like this (very early in your main script):

lappend auto_path [file join [file dirname [info script]] my_app_pacakges]
# If the script is in foo/bar.tcl then packages are in or below foo/my_app_packages

这篇关于无法从用Tcl编写的应用程序中找到软件包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆