Is the order of a class properties guaranteed in a foreach?


#1

Hi,

I use some shared classes to send/receive data between my agent and my device codes. Basically, those classes are defined in 1 single file “models_common.nut” imported in “agent.nut” and “device.nut” so I am 100% sure both have the same version of the models.

I have also written 2 utility functions to serialize / unserialize this kink of data. Everything is based on the assumption that a foreach on the class entries will get the entries in the exact same order, each time and on both side of the code.

This currently works, but I cannot see any specification that says that this will always work in the future. Any opinion?

Below a sample of my code.

Thanks!

// file "models_common.nut"

class Measure {
    field1 = null;
    field2 = null;
    field3 = null;
    ...
}

//
// Generic serialize / unserialize
// Here, I had a look at the Electric Imp Serializer module but I want to make it simpler
//

function serialize(obj) {
    local data = array(64); // make a guess on the size
    local i = 0;

    foreach (k, v in obj.getclass()) {
        if (typeof v != "function") {
            data[i++] = obj[k];
        }
    }

    data.resize(i);

    return data;
}

function unserialize(obj, data) {
    local i = 0;
    foreach (k, v in obj.getclass()) {
        if (typeof v != "function") {
            obj[k] = data[i++];
        }
    }

    return obj;
}
// file "device.nut"
local measure = Measure()
measure.field1 = 123
...

agent.send("measure", serialize(measure))
// file "agent.nut"
device.on("measure", function(data) {
    local measure = unserialize(Measure(), data);
    ...
}

#2

I don’t believe class entries are ordered - order depends on the hashing of the keys, as it’s essentially a table.

Is there a reason you couldn’t use an array with tuples of [field, data]? That would be guaranteed order.


#3

The goal is simply to avoid sending the same field names over and over, which does not bring any value. So if I have a quick solution to send only the data, I take it.

If as you say, the order “depends on the hashing of the keys”, then that’s good. I don’t need the order to correspond to the order I specified the keys in my code, I need to the order to be consistent between each call. But maybe it was not what you meant?


#4

The order of class properties in a foreach is not guaranteed. It is not even guaranteed to be the same in the agent as it is on the device, given common source.

Peter