2016-11-14 1 views
-3

v1- old var, v2 - new var .. Actuellement, si quelqu'un définit v1, il fera une erreur, donc je rends l'arrière compatible. Donc, si vieux var v1 est défini où je veux faire ces 2 variables les mêmes à savoir v2 = v1 (également valeur de v1 devrait être dans v2)Rendre les anciennes et les nouvelles variables rétrocompatibles

jeu de test v1

Pour cela, j'ai un hachage avec le vieux et de nouveaux noms

set oldvars(v1) v2 


    foreach ele [array names oldvars] { 
    if {([info exists ele] || $ele == "") && $oldvars($ele)!= ""} { 
     o2n $ele $oldvars($ele) //o2n is a proc defined below 
    } 
    } 

    proc o2n {gvar gval} 
     global v1 
     puts "gvar is $gvar, gval is $gval" //prints gvar - v1 and gval - v2 
     set $gval [set $$gvar] **//Error - Cant read $v1 no such variable. Above line does print gvar = v1 so $$gvar should be $v1 =test** 
     puts "$gval [set $gvar]" // Has the value of v1 i.e test 
    } 

puts "v2 is $v2" **: Error : Can't read v2 no such variable** 

Répondre

1

Si nous présumons

set a1 1 
set b1 2 
set c1 3 

set oldvars(a1) a2 
set oldvars(b1) b2 
set oldvars(c1) c2 

Tout ce que vous devez faire pour copier les valeurs de x 1 variables correspondant x 2 variables est

foreach {x1 x2} [array get oldvars] { 
    set $x2 [set $x1] 
} 

L'affectation ressemble un peu à l'écart, mais ce que cela signifie est « attribuer à la variable dont le nom est en x2 la valeur de la variable dont le nom est en x1.

Si vous voulez faire cela via une procédure, vous devez prendre en compte que le code de la procédure s'exécute dans une autre portée. La commande uplevel aide à cela, et comme sideeffect le code d'affectation devient plus simple:

proc o2n {x1 x2} { 
    upvar 1 $x1 v1 $x2 v2 
    set v2 $v1 
} 

foreach {x1 x2} [array get oldvars] { 
    o2n $x1 $x2 
} 

Vérifier l'existence

Si vous gardez des références à des variables sous forme de variables qui stockent les noms de ces variables, le test de l'existence semble également différent de l'habituel. Si vous avez

foreach ele [array names oldvars] { 

la ele variable est garanti d'exister (il est créé par foreach tant que la liste ne soit pas vide - mais le corps de foreach ne sera pas exécuté de toute façon), mais il isn 't la variable que vous vouliez vérifier: elle ne contient que le nom de la variable que vous vouliez vérifier. Ainsi, vous aurez besoin d'écrire le test comme celui-ci:

info exists $ele 

(vous devez également être dans le même champ où existe la variable référencée par ele).

Cela semble très étrange puisque nous sommes généralement très prudent de vérifier le nom de la variable, et non la valeur . Mais dans ce cas, la valeur de la variable est le nom que nous voulons vérifier, donc.

À l'intérieur de la procédure, il est plus facile d'écrire le test. La commande upvar crée des noms dans les portées actuelles qui sont liées à des variables dans une autre portée. Si ces variables n'existent pas, les noms locaux seront en effet des noms de variables non définies.

upvar 1 $x1 v1 $x2 v2 
if {[info exists v1]} { 

Documentation: array, foreach, if, info, proc, set, upvar

+0

Merci beaucoup. Ça marche! – Rancho