Trying to iterate thru TMap = no error

Archives Forums/BlitzMax Bug Reports/Trying to iterate thru TMap = no error

GfK(Posted 2012) [#1]
Tripped myself up a couple of times on this one already, should this not be throwing an exception since the object is a TMap, not an enumerator?

Strict

Local myMap:TMap = New TMap

myMap.Insert("Foo", "Bar")

For Local S:String = EachIn myMap 'should be myMap.Values() or myMap.Keys()
  Print S
Next



TomToad(Posted 2012) [#2]
Not a bug. Iterating through a TMap will iterate through the nodes. A node contains both a value and a key.
Strict

Local myMap:TMap = New TMap

myMap.Insert("Foo", "Bar")

For Local Node:TNode = EachIn myMap 'should be myMap.Values() or myMap.Keys()
  Print String(Node.Key())+" "+String(Node.Value())
Next



GfK(Posted 2012) [#3]
OK, I accept that. But even so, surely there should be an error as in my original code, I'm trying to iterate through a bunch of TNodes using a String. Logically I would expect "Unable to convert 'TNode' to 'String'".


TaskMaster(Posted 2012) [#4]
I have not tested, but does that actually iterate through each TNode?

When you iterate through a list with a variable, usually what happens is you only get an event each time the variable type matches.

So I would think your first example would try to iterate through the TMap trying to find Strings and never actually enter the loop as it never found a string in the List.

Does that make sense?


col(Posted 2012) [#5]

Logically I would expect "Unable to convert 'TNode' to 'String'".



Yes, I agree.

The underlying problem is that a String is treated an Object. If you cast from one Object type to another Object and its not of the same type then the cast will silently fail. If you try to cast to/from an Int or some other atomic type then the compiler will complain as expected.

Slightly OT, but related -
This problem is even more compounded because Strings are also treated differently to an Object, specifically when casting between an Object array thats initialized with Strings as elements ( which creates an array of Strings ) compared to an Object array that has Strings assigned to the elements at a later time ( which creates an array of Objects ). The former will take a cast to a String[], whereas the latter needs each element cast individually. I've looked into BRLs code and there doesn't seem an easy fix for it. The whole underlying 'default type' identifying algorithm would need to be worked on in several places.


Zeke(Posted 2012) [#6]
"Logically I would expect "Unable to convert 'TNode' to 'String'". " no..
[bbcode]
For local s:STRING EachIn MYMAP
[/bbcode]
^^ you are looking STRINGS,,, not nodes
your MYMAP contains only TNode(s)

Last edited 2012


col(Posted 2012) [#7]
Yes, but my point is that Strings should be treated as atomic not an Object.

So a compiler reaction similar to trying to use

For Local S:Int = EachIn MyMap

is too much?

An Int isn't treated as an Object so it wouldn't even compile and you'd know immediately somethings wrong in the syntax. But String IS treated as an Object and goes through the Object casting algos which fail silently when the cast isn't satisfied. If Strings were treated as an atomic type and not an Object then it wouldn't compile as Gfk and I would expect. There's nothing that you can do with a String other than use it with other String(s), so why is it an Object?