https://toitlang.org/ logo
How to detect the data type of an object?
# help
k
The value of '**nested**' should be detected as '**map**'. How can I achieve this ?
Copy code
map := {
            "simple":"value", 
            "nested": 
              {
                "A":1,
                "B":2
              }
          }
f
You can do an
is Map
check
Or do you mean statically? Statically you need to use
as
or assign it to a typed local:
Copy code
nested/Map := map["nested"]
or
Copy code
(map["nested"] as Map)...
k
so simple 😳 Thank you (die Verkalkung beginnt mit der Geburt)
I searched for 'is' in Toit docs, but couldn't find anything. Neither part of language, nor part of object. How is it implemented ?
f
Each object (except for small integers) have a class-id in their header.
If you are testing for an object, a small range-check can detect whether an object is in a class-hierarchy.
If you are testing for an interface, then we add
is-interface
methods to these classes.
These methods don't actually have any code, since we just check for their existence.
Integers are implemented differently: they are not actual objects, but their value shifted.
So the value 3 is simply
3 << 1
==
6
.
To differentiate them from pointers to objects, pointers are offset by 1.
So all object pointers in the Toit VM have the last bit set to
1
.
So
is int
starts by looking whether the "pointer" has 0 in the least-significant bit. If not, it also checks for the
Integer
class-id, which is used when values are bigger than 31 bits (since they wouldn't fit into words anymore).
You can see the class-ids, by running
toit tools snapshot classes my-snapshot
.
f
is
should be in there.
Where does the table come from?
k
f
(btw: there is also
is not
, as in
if x is not Map
)
I will update the table.
k
👍🏻
f
we probably missed it, because we have
is
and
is not
as operators in our parser.
k
... there are a lot of muggles outside hogwarts
If I try to create a composed map :
Copy code
m-a := { "A":1 }
  m-b := { "B":2 } 
  m-composed := { m-a, m-b }
this way does not work. Is there a way to combine maps ?
f
The
{ m-a, m-b }
is a set.
You can either make a list:
[m-a, m-b]
, or a map:
{"m-a": m-a, "m-b", m-b}
. Toit doesn't have JavaScript's automatic "use the variable name as key".
k
Copy code
m-composed := { m-a.first: m-a, m-b.first: m-b}
Is that the correct way to create it using the data of the 2 predefined maps ? It seems to work, but is ugly.
Copy code
m-composed := {:}
m-a.do: | k v |  m-composed[k] = v
m-b.do: | k v |  m-composed[k] = v
*... found another way *
f
Yes. the second approach is nicer.
k
I am preparing the technique to deal with maps. Goal is setup for home assistant device discovery ...
f
Updated table is live.
k
for those interested in maps:
Copy code
map-elements := { "A":1, "B":2, "C":3 }

map := {"key":"value"}
map["k"] = "v"

// to add elements to map
map-elements.do (: |k v| map[k] = v)


map["nested"] = {:} // create "nested" sub-map
(map["nested"])["k"] = "v" // add one k-v-element to sub-map

// / to add elements to sub-map
map-elements.do (: |k v| (map["nested"])[k] = v)

sub-map := map["nested"]   // easier to read
sub-map["key"] = "value"
...
- 128 nesting levels supported !