如何将 TCL 过程的结果保存在列表中?

How to save result of a TCL proc in a list?

我的TCL脚本是这样的:

proc foo {var1} {
    ;# some code which finds a value (say bar) and recursively call the same proc (foo) on bar until it reaches end of data.
}

现在我想将所有值(栏)保存到列表中。

当我在 proc 中设置一个列表时,每次递归调用 proc 时它都会重置。当我在 proc 之外设置时,它没有找到它并说变量不存在。

我该如何实现?

谢谢。

编辑:

下面是示例代码:

set mylist {}

proc myproc {var} {

set exception {tesla}
set var1 [#some script to fetch a data string using proc variable]

foreach item $var1 {
    set var2 [#script to get another data depending on item]

    if {$var1==2 || $var2=="tesla"} {

        set var3 [#script to get some data using var2]

        puts "debug value $var3"
        lappend mylist $var3
        myproc $var3
    }
  }
}

您将需要 lappend 来存储每次递归调用的输出。

proc glob-r-dir {{dir .}} {
    set res {}
    foreach i [glob -nocomplain -dir $dir *] {
        if {[file type $i] eq {directory}} {
            lappend res $i
            eval lappend res [glob-r-dir $i] ;# recursive call to function
        }
    }
    set res
}

打电话的时候可以这样打电话,

set dirs [glob-r-dir "/home/abc"]

在这里,您将在 dir 变量中获得 return 值。

我在里面找到这个 "Recursive Glob Section" Click on This

解决方案 1

proc foo {var1 resultVar} {
    upvar $resultVar result
    if {$var1 == 1} {
        lappend result 1 
        return $result
    } else {
        lappend result $var1
        foo [expr $var1 - 1] result
    }
}

set myResults []
foo 10 myResults
puts "From foo: $myResults"

解决方案 2

proc bar {var1} {
    global barResults
    if {$var1 == 1} {
        lappend barResults 1 
    } else {
        lappend barResults $var1
        bar [expr $var1 - 1]
    }
}

set barResults []
bar 10
puts "From bar: $barResults"

输出

sharad@ss:~$ tclsh my.tcl 
From foo: 10 9 8 7 6 5 4 3 2 1
From bar: 10 9 8 7 6 5 4 3 2 1
sharad@ss:~$ 

通常,当您通过搜索步骤处理这样的列表时,通常会更新列表,使其仅包含要搜索的剩余元素。该列表本身存储在提供给被调用例程的调用者的一个变量中;如果它在局部变量中,则不会影响外界。 name-provision 与 upvar 一起使用,因此内部搜索过程不需要在其调用者中具有关于变量命名的内置知识(因为那会是 terrible 样式)。如果需要,调用者可以将列表复制到局部变量中

proc innerSearch {listVariable} {
    upvar 1 $listVariable theList
    set idx [...];            # Get index of thing we found
    set resultValue [...];    # Thing that we will return
    set theList [lrange $theList [expr {$idx + 1}] end]
    return $resultValue
}

proc outerSearch {} {
    global foobar
    set myList $foobar;       # Copy here! Actually does efficient magic behind the scenes
    set results {}
    while 1 {
        set foundThing [innerSearch myList];   # Note: we pass the variable *NAME*
        if {$foundThing eq ""} break;          # Terminate the loop if not found
        lappend results $foundThing
    }
    return $results
}

如果另一方面你还需要知道找到元素的索引以便对其进行处理,你可以将前一个索引安排在存储的变量中,然后只传递列表按价值计算。

proc innerSearch {list indexVariable} {
    upvar 1 $indexVariable idx
    # Use old index to start search        
    set idx [...];            # Get index of thing we found
    set resultValue [...];    # Thing that we will return
    return $resultValue
}

proc outerSearch {} {
    global foobar
    set index -1;             # Before any element
    set results {}
    while 1 {
        set foundThing [innerSearch $foobar index];   # Note: we pass the variable *NAME*
        if {$index == -1} break;          # Terminate the loop if not found
        lappend results $foundThing
    }
    return $results
}

如果您使用的是当前推荐的 Tcl (8.6) 版本,您或许可以将简单的搜索转换为 lmap 调用。我不知道这里是不是这样。