如何将TCL进程的结果保存在列表中?
我的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外部设置时,它没有找到它,并且说变量不存在 我如何做到这一点 谢
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{}。我做错什么了吗?谢谢,这正是我想要的。谢谢,这正是我想要的。