2016-04-11 23 views
0

私のTCLスクリプトは、このようなものです:TCL 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 
    } 
    } 
} 

答えて

1

ソリューション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" 

出力通常

[email protected]:~$ 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 
[email protected]:~$ 
+0

ありがとう、これは私が探していたものです。 – ABX

+0

編集Donal :)ありがとうございますそれを感謝します! – Sharad

0

あなたは、各再帰呼び出しに出力を格納する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変数であなたの戻り値を取得します。

とき」私は、 "再帰グロブ節" 内部Click on This

+0

ありがとうございましたAxT、しかし私はそれを動作させることができませんでしたそれは空のリストを返します。 私は似たような試みをしましたが、procが呼び出されるたびにres {}が呼び出されました。 何か間違っていますか? – ABX

+0

問題のコードを共有してもらえますか? –

+0

オリジナルの投稿を更新しました – ABX

1

ここでこれを見つけましたr検索のステップでそのようなリストを操作すると、検索する残りの要素だけが含まれるようにリストを更新するのが普通です。リスト自体は、呼び出されたルーチンに提供される呼び出し側の変数に格納されます。それがローカル変数にあれば、それは外界に影響を与えません。名前提供は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呼び出しに簡単な検索を変換することができるかもしれません。それがここに当てはまるかどうかはわかりません。