Version 3 of dict with

Updated 2009-01-23 04:10:09 by andy

One of the subcommands of dict. Moves entries from a dictionary into variables, evaluates a script, and moves the (possibly updated) values back from the variables to the dictionary.

   set info [dict create forenames "Joe" surname "Schmoe" street "147 Short Street" city "Springfield" phone "555-1234"]
   dict with info {
      puts "   Name: $forenames $surname"
      puts "   Address: $street, $city"
      puts "   Telephone: $phone"
   }

The idea comes in part from the with statement of Pascal, which temporarily places the fields of a record into the local scope. A difference is that in Pascal the record fields merely shadow similarly-named variables, whereas dict with really puts the values into ordinary variables. Because of this, one should only use dict with to unpack dictionaries which have a known set of entries (like a Pascal record or C struct).

An alternative technique is to unpack dictionaries into arrays using array set (and repack them with array get). This is safe for dictionaries which may gain new elements.


jima (2008-09-02)

Just a question...perhaps a silly one...

dict with creates new variables (taken from the entries of the dictionary) and evaluates a script that might use them. So far so good.

Would it make sense to destroy the created variables immediately after the execution of the script?

I think this way there would be no cluttering at the level that called dict with caused by the new variables.

I mean:

 set a [dict create foo bar]
 dict with a {
  puts $foo
 }
 #Now I have from now on another foo variable that might be considered 'clutter' from this point on...

In a sense, I feel the same about variables created in for {set i 0} ..., they remain after the loop has completed. Should the variable i be created outside the for initialization then I think it should stay, but otherwise...would it not be cleaner to remove it?

DKF: It's never worked like that in the past.

AMG: As a consequence, it's very easy to unpack a dict into local variables:

proc print_stuff {args} {
   dict with args {}
   puts "a=$a b=$b locals={[info locals]}"
}
print_stuff a 1 b 2 c 3
# prints "a=1 b=2 locals={args a b c}"

Of course, changes made to the local variables created in this way don't magically find their way back into the original dict.

The "dict with args {}" idiom goes great with [coroutine].