2016-06-30 21 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

は、ファイルの前に$を削除してください:DictAddファイルベースライン$ファイル名。 –

答えて

0

ことはあなたの辞書のですが、辞書変数のDictAdd期待しています。代わりに、このように呼び出すと:

DictAdd files baseline $fileName 

コマンドは設計どおりに動作します。

ところで:あなたはこのよう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; "ファイル"に含まれます)を取ります。実行コマンドの外側に変数を配置したものを使用して、実行コマンド内にローカルエイリアスを作成します(この場合、dictionaryfiles外部は基本的にはdictionaryと同じ変数です)。他に何かを渡すとfilesの値、たとえば{baseline {a b c}}upvar{baseline {a b c}}という変数を探し、見つからない可能性があります。とにかくエイリアスが作成され、初期化すると、実際に呼び出し元のレベルで{baseline {a b c}}という変数が作成されます。しかし、やはり変数の名前を使用したいと思うでしょう(もちろん、変数の名前は、あなたがコマンドを呼び出すときに別の変数の値かもしれません...)。

ドキュメント:dictiflappendniオペレータ、procupvar

+0

ありがとう、ピーター。これは完全に機能しました。私はまだ、あなたが言うように、プロシージャはその値ではなく辞書変数の名前を期待しているのはなぜなのかを考えようとしています。 –

+0

@BruceJohnson:私は説明を加え、それが助けにならないかどうか教えてください。 –

+0

@BruceJohnson:今説明が実際に追加されました。私は保存せずにページを閉じたようです。 –

0

あなたが参照している辞書変数は実際には設定されておらず、読むことができない可能性が高いです。このお試しください:呼び出し

DictAdd $files baseline $fileName 

$files

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 
    } 
} 
関連する問題