2016-06-30 4 views
0

값이 사전 목록에없는 경우에만 사전 목록에 값을 추가하려고합니다. 따라서, 나는 프로 시저에이를 분리하기 위해 노력하고있어, 나는 다음과 같은 코드가이를하지 않는 이유를 알아낼 수 없습니다 :사전 키가없는 경우에만 사전 키 값 추가

proc DictAdd {_dictionary key value} { 

    upvar 1 $_dictionary dictionary 

    if { $value ni [dict get $dictionary $key] } { 
     dict lappend dictionary $key $value 
    } 
} 

이 프로 시저를 호출하면 다음과 같은 오류 반환 :

can't read "dictionary": no such variable 
    while executing 
"dict get $dictionary $key" 
    (procedure "DictAdd" line 5) 
    invoked from within 
"DictAdd $files baseline $fileName" 
    (procedure "getFilesToLoad" line 53) 
    invoked from within 
... 

누군가 내가 여기서 잘못하고있는 것을 말해 줄 수 있습니까? 감사.

+0

upvar 파일 앞에 $를 제거해보십시오 : DictAdd이 기준 $ 파일 이름을 파일. –

답변

0

를 호출

DictAdd $files baseline $fileName 

$files에서하면 사전의 이지만, DictAdd이름 사전 변수의을 기대하고있다. 대신 다음과 같이 호출하면 :

DictAdd files baseline $fileName 

명령은 설계된대로 작동합니다.

은 BTW :이 같은 DictAdd를 정의하는 경우 : 키가없는 경우

proc DictAdd {_dictionary key value} { 
    upvar 1 $_dictionary dictionary 

    if {[dict exists $dictionary $key]} { 
     dict with dictionary { 
      upvar 0 $key values 
      if {$value ni $values} { 
       lappend values $value 
      } 
     } 
    } else { 
     dict lappend dictionary $key $value 
    } 
} 

하면 오류 메시지가 표시되지 않습니다 (사전 여전히 외부에 존재해야합니다 (이것은 그 키에 값을 추가) DictAdd) 점검/추가 코드가 조금 덜러워집니다.

이름이 뭔가요? upvar의 작동 방식 때문입니다. 이 명령은 스택 레벨 (이 경우에는 1 = 호출자의 레벨)과 변수 이름 (이 경우에는 _dictionary; "파일"에 포함됨)을 취합니다. 실행 명령 외부에서 변수를 찾는 명령을 사용하고 실행 명령 내에 로컬 별칭을 만듭니다 (이 경우 dictionary : files 외부는 기본적으로 내부에서 dictionary과 동일한 변수 임). 다른 것을 전달하면 (예 : files의 값인 {baseline {a b c}}, upvar{baseline {a b c}}이라는 변수를 찾아 가장 가능성이 높습니다. 어쨌든 별칭이 만들어지며 초기화하면 호출자 수준에서 {baseline {a b c}}이라는 변수가 실제로 만들어집니다. 그러나 다시, 당신은 변수의 이름을 사용하기를 원할 것입니다 (물론 변수의 이름은 명령을 호출 할 때 다른 변수의 값이 될 수 있습니다 ...).

문서 : dict, if, lappend, ni 운영자, proc,

+0

고마워, 피터. 이것은 완벽하게 작동했습니다. 나는 아직도 그 이유가 무엇인지 알아 내려고하고있다. 당신이 말했듯이 프로 시저는 값보다는 사전 변수의 이름을 기대하고있다. –

+0

@ BruceJohnson : 설명을 추가했는데 도움이되지 않는 경우 알려주세요. –

+0

@ BruceJohnson : 이제 설명이 실제로 추가되었습니다. 저장하지 않고 페이지를 닫은 것 같습니다. –

0

당신이 말하는 사전 변수가 실제로 설정되어 있지 않으므로 읽는 것이 불가능할 가능성이 큽니다. 이 시도 :

proc DictAdd {_dictionary key value} { 
    upvar 1 $_dictionary dictionary 
    if {![info exists dictionary]} { 
     set dictionary [dict create $key [list $value]] 
    } elseif {$value ni [dict get $dictionary $key]} { 
     dict lappend dictionary $key $value 
    } 
}