Odd exception when comparing a xojo.core.dictionary value with a string

I know that there are some gotchas when using xojo.core.dictionary after loading with ParseJSON, but I can’t figure this one out. I have a xojo.core.dictionary that is loaded with ParseJson. This comparison

if d.value(“aText”) = “someString” then

gives a TypeMismatchException (both the key and the value for aText are of type Text)

But this doesn’t throw the exception

dim s as string = d.value("aText")
if s = "someString" then

I can’t reproduce the problem with with Text that I create in code, e.g. the following does not throw an exception

dim t as Text = “aText”
if t = “aString” then

A bug that I should report, or something I should expect with the new framework?

I think it should be

if d.value(aText) = "someString" then

since you say aText is a Text variable.

I haven’t looked into this closely, but offhand it certainly looks like some kind of issue. At the very least, the error messages are absolutely unhelpful.

I have seen crazy stuff like this, too, with the Xojo.Core.Dictionary. It has to do with text literals somehow being different from a Text variable.

It’s enough to pull your hair out. If you have hair. Which I don’t. But it does make me swear at the Xojo engineers (sorry Joe) when I come across it. For this reason I’m not spending much time in the new framework.

Here’s the Verified Feedback report I filed back in November. <https://xojo.com/issue/41661>

Thanks. I’ll see if I can come up with a simple example project and file a feedback.

“aText” and “someString” are only of type Text, if you are using the “Using Xojo.Core” clause. If not they would be of type String (unless it is an iOS project of course).

Yes, I do believe that there is some string/text issue going on here. While digging into this I came across another unexpected (at least to me) observation – .toString doesn’t seem to honor the string encoding. Example:

dim s as string = “test” // s is UTF-8
dim t as text = s.toText // t is UTF-16

Text/string literals do not work like this. Their type is contextual, based off of the literal’s usage.

From the language’s perspective text literals:

  • Implicitly convert to String with no conversion penalty.
  • Implicitly convert to Text with no conversion penalty.
  • Implicitly convert to an Auto containing a Text.
  • Implicitly convert to a Variant containing a String (for backwards compatibility).

The conversion penalty refers to overload resolution, which is described fairly well in the second paragraph of a blog post about method overloading.

[quote=268498:@Jonathan Ashwell]Yes, I do believe that there is some string/text issue going on here. While digging into this I came across another unexpected (at least to me) observation – .toString doesn’t seem to honor the string encoding. Example:

dim s as string = “test” // s is UTF-8
dim t as text = s.toText // t is UTF-16[/quote]

How are you making this observation?

This sounds disturbing…

In this example:

Dim dct As New Xojo.Core.Dictionary() dct.Value("aKey") = "abc" MsgBox dct.Value("aKey")
will “aKey” be a String or a Text? How can I enforce one of the two (without using a Dim statement) if not by a Using Xojo.Core clause?

I made a new project and placed those two lines of code in a button. The encodings are what I see in the debugger.

<https://xojo.com/issue/44067>

I don’t see any encoding information for the Text variable. Could you post a screenshot?

Left is a Text, right is a String

So a TypeMismatch.

As proven by

[quote=268385:@Jonathan Ashwell]But this doesn’t throw the exception

dim s as string = d.value("aText")
if s = "someString" then

[/quote]

Implizit conversion to string.

Note : “(both the key and the value for aText are of type Text)” is the LEFT side of the comparison only.

So the question is what happens in the implizit conversion from String to Text.

Is there one? Which encoding?

Strings have a standard UTF8 encoding.

If the Encoding is set to Nil in the implizit conversion then what happens?

Should there be an implizit conversion in the first place?

Doubtful. Xojo.Core.Dictionary keys are of the Auto type, which precisely has no implicit conversion.

So technically these keys are different :

dim myKey as Text = "whatever" NewFrameworkdico.value(mykey) = "something"
and

dim myKey as String = "whatever" NewFrameworkdico.value(mykey) = "something"

[quote]So technically these keys are different :

dim myKey as Text = “whatever”
NewFrameworkdico.value(mykey) = “something”
and

dim myKey as String = “whatever”
NewFrameworkdico.value(mykey) = “something”[/quote]

Non-technically, this is a mess.
How could anyone hoping to learn Xojo for the first time deal with that?

[quote=268636:@Michel Bujardet]Doubtful. Xojo.Core.Dictionary keys are of the Auto type, which precisely has no implicit conversion.

So technically these keys are different :

dim myKey as Text = "whatever" NewFrameworkdico.value(mykey) = "something"
and

dim myKey as String = "whatever" NewFrameworkdico.value(mykey) = "something"[/quote]
Yes, because dictionary keys are objects.

[quote=268644:@Jeff Tullin]Non-technically, this is a mess.
How could anyone hoping to learn Xojo for the first time deal with that?[/quote]

One learning to ski won’t venture right away on the black track. Dictionaries are very powerful, and as such, have a learning curve. The idea that Xojo being for “ordinary people” they would be dispensed of acquiring enough knowledge to master certain concepts is at best naive.

These keys in a Xojo.Core.Dictionary are identical :

dim myKey as Text = "whatever" NewFrameworkdico.value(mykey) = "something"
and

dim myKey as String = "whatever" NewFrameworkdico.value(mykey.ToText) = "something"

But no need to use Xojo.Core.Dictionary and the Text data type to have this kind of subtleties. Here is an example with classic dictionary :

[code] Dim s as string = “whatever”
Dim s1 as string = DefineEncoding(“whatever”, Encodings.UTF16)

dim dic as new dictionary

dic.value(s) = “One”
dic.value(s1) = “Two”

system.DebugLog(dic.value(s)) // -> One
system.DebugLog(dic.value(s1)) // -> Two[/code]

So even between two strings if the encoding differ, they will be two different keys.

This is what I see in the debugger.