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

如何将TCL进程的结果保存在列表中?,tcl,proc,Tcl,Proc,我的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外部设置时,它没有找到它,并且说变量不存在 我如何做到这一点 谢

我的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
变量中获得返回值


我在这里的“递归Glob部分”中找到了它

您需要
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
变量中获得返回值

我在“递归全局部分”中找到了这个解决方案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:~$ 
解决方案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:~$ 

通常,当您使用搜索步骤处理这样的列表时,通常会更新列表,使其仅包含要搜索的剩余元素。列表本身存储在调用者中的变量中,该变量提供给被调用的例程;如果它位于局部变量中,则不会影响外部世界。名称规定与
upvar
一起使用,这样内部搜索过程就不需要具备调用程序中变量命名的内置知识(因为这是一种糟糕的风格)。如果有必要,调用方可以将列表复制到局部变量中

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
调用。我不知道这里是否是这种情况。

通常,当您通过搜索步骤处理这样的列表时,通常会更新列表,使其仅包含要搜索的剩余元素。列表本身存储在调用者中的变量中,该变量提供给被调用的例程;如果它位于局部变量中,则不会影响外部世界。名称规定与
upvar
一起使用,这样内部搜索过程就不需要具备调用程序中变量命名的内置知识(因为这是一种糟糕的风格)。如果有必要,调用方可以将列表复制到局部变量中

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
调用。我不知道这里是否是这样。

谢谢AxT,但我无法让它工作,因为它返回空列表。我尝试了类似的方法,但每次调用proc时都会调用set res{}。我做错什么了吗?谢谢AxT,但我无法让它工作它返回空列表。我尝试了类似的方法,但每次调用proc时都会调用set res{}。我做错什么了吗?谢谢,这正是我想要的。谢谢,这正是我想要的。