From: cattaghia on
Hi everyone!

The docs about Tcl 8.5 "dict" don't tell me about errors which could
be returned from "dict exists". However, I keep getting "missing value
to go with key" with a code snippet like this:

# "arg" is supposed to be a string, but it might happen that it comes
as a dict, because the
# procedure receives an "args" list and a user might misplace things
if { [string is list $arg] } {
# hmm, arg looks like a list, so it may really be a dict, and if
this is the case this dict
# will certainly contain a key called "-certainkey". Let's check:
if { [dict exists $arg -certainkey] } {
# do things that would be done with the dict
}
}

Okay. And then the whole thing crashes. Firstly, because, according to
tkcon, the "dict exists" command above generates the "missing value to
go with key" error. Secondly, because it was not even supposed to run
-- I tested it in a way to assure that "arg" in this case would be a
regular string, so I presume that "string is list" failed as well.

Any clues, please?

Thanks and regards!
From: Gerald W. Lester on
cattaghia wrote:
> Hi everyone!
>
> The docs about Tcl 8.5 "dict" don't tell me about errors which could
> be returned from "dict exists". However, I keep getting "missing value
> to go with key" with a code snippet like this:
>
> # "arg" is supposed to be a string, but it might happen that it comes
> as a dict, because the
> # procedure receives an "args" list and a user might misplace things
> if { [string is list $arg] } {
> # hmm, arg looks like a list, so it may really be a dict, and if
> this is the case this dict
> # will certainly contain a key called "-certainkey". Let's check:
> if { [dict exists $arg -certainkey] } {
> # do things that would be done with the dict
> }
> }
>
> Okay. And then the whole thing crashes. Firstly, because, according to
> tkcon, the "dict exists" command above generates the "missing value to
> go with key" error. Secondly, because it was not even supposed to run
> -- I tested it in a way to assure that "arg" in this case would be a
> regular string, so I presume that "string is list" failed as well.
>
> Any clues, please?

First off most strings are lists.

Second off, catch is your friend.

Lastly, for non-nested dicts, you could change your first check to:

if {[string is list $arg] && ([llength $arg] % 2) == 0] {

Then you can be certain that dict exists will raise an error (although it
may well return a 0).

--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
From: Donal K. Fellows on
On 25/04/2010 17:02, cattaghia wrote:
> The docs about Tcl 8.5 "dict" don't tell me about errors which could
> be returned from "dict exists". However, I keep getting "missing value
> to go with key" with a code snippet like this:

Did you know that you can script a [string is_dict] in yourself? (OK,
not *quite* the same as a [string is dict], but close...)

proc my_string_is_dict string {
expr {[string is list $string] && ([llength $string] & 1) == 0}
}
set m [namespace ensemble configure ::string -map]
dict set m is_dict ::my_string_is_dict
namespace ensemble configure ::string -map $m

There you go! Updated the core [string] command to do that bit extra!

Donal.
From: cattaghia on
Thank you for the suggestions, Gerald and DKF. I am not sure if the
pair-checking division will work because it is possible that the
received dict contain a nested dict in it. Anyway, I will try to
simplify this and get rid of all this stuff.

By the way, just for curiosity, how does "string is list" work? As
Gerald said, "most strings are lists"... I can't see how Tcl can state
that "Tom is a cat" is a string and not a four-elements list.


Fabricio Rocha



On Apr 25, 4:13 pm, "Donal K. Fellows"
<donal.k.fell...(a)manchester.ac.uk> wrote:
> On 25/04/2010 17:02, cattaghia wrote:
>
> > The docs about Tcl 8.5 "dict" don't tell me about errors which could
> > be returned from "dict exists". However, I keep getting "missing value
> > to go with key" with a code snippet like this:
>
> Did you know that you can script a [string is_dict] in yourself? (OK,
> not *quite* the same as a [string is dict], but close...)
>
>    proc my_string_is_dict string {
>        expr {[string is list $string] && ([llength $string] & 1) == 0}
>    }
>    set m [namespace ensemble configure ::string -map]
>    dict set m is_dict ::my_string_is_dict
>    namespace ensemble configure ::string -map $m
>
> There you go! Updated the core [string] command to do that bit extra!
>
> Donal.

From: Donal K. Fellows on
On 25 Apr, 21:03, cattaghia <cattag...(a)ig.com.br> wrote:
> By the way, just for curiosity, how does "string is list" work?

It uses a special version of the list parser in the case that the
string is not already annotated with metadata saying that it parses
correctly. The special parser is a little slower, but can produce more
information on errors.

> As Gerald said, "most strings are lists"... I can't see how Tcl can
> state that "Tom is a cat" is a string and not a four-elements list.

Oh, but it *is* a four-element list! And a string as well at the same
time. Types are merely a matter of perspective. "So what I told you
was true... from a certain point of view." "A certain point of view?"
"Luke, you're going to find that many of the truths we cling to depend
greatly on our own point of view."

Donal.