2016-04-11 1 views
0

scénario Mon TCL est comme ceci:Comment enregistrer le résultat d'un processus TCL dans une liste?

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. 
} 

Maintenant, je veux sauver toutes les valeurs (bar) à une liste.

Lorsque je définis une liste à l'intérieur du proc, elle se réinitialise à chaque fois que le proc est appelé récursivement. Quand je me place en dehors du proc, il ne le trouve pas et dit que la variable n'existe pas.

Comment puis-je y parvenir?

Merci.

Edit:

Voici l'exemple de code:

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 
    } 
    } 
} 

Répondre

1

Solution 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" 

Solution 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" 

Sortie

[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

Merci, c'est exactement ce que je cherchais. – ABX

+0

Merci pour l'édition Donal :) Appréciez-le! – Sharad

0

Vous aurez besoin lappend pour stocker la sortie de chaque appel récursif.

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 
} 

Tout en appelant, vous pouvez appeler comme ça,

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

Ici, vous obtiendrez votre valeur de retour dans la variable dir.

Je trouve cela ici à l'intérieur "récursive Glob section" Click on This

+0

Merci AxT, mais je ne pouvais pas le faire fonctionner Il retourne la liste vide. J'ai essayé quelque chose de similaire mais l'ensemble res {} est appelé à chaque fois que proc est appelé. Est-ce que je fais quelque chose de mal? – ABX

+0

Pouvez-vous s'il vous plaît partager votre code en question? –

+0

mis à jour le message original – ABX

1

En règle générale, lorsque vous » r En parcourant une liste comme celle-ci avec une étape de recherche, il est habituel de mettre à jour la liste afin qu'elle ne contienne que les éléments restant à rechercher. La liste elle-même est stockée dans une variable de l'appelant fournie à la routine appelée; si c'est dans une variable locale, cela n'affectera pas le monde extérieur. Le provisionnement de nom est utilisé avec upvar, de sorte que la procédure de recherche interne n'a pas besoin d'avoir une connaissance intégrée de la dénomination des variables dans son appelant (parce que ce serait terrible style). L'appelant peut copier la liste dans une variable locale si cela est nécessaire

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 
} 

Si d'autre part vous devez savoir aussi l'indice que vous avez trouvé l'élément à afin de les traiter, vous pouvez organiser la l'index précédent doit être dans la variable qui est stockée, et juste passer la liste par valeur.

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 
} 

Si vous utilisez la version actuelle recommandé de Tcl (8.6), vous pourriez être en mesure de convertir des recherches simples dans lmap appels. Je ne peux pas dire si c'est le cas ici.