Explanation of seemingly very odd symbol syntax crash.

Hi,

I've modified my code to avoid this, but I don't see why the syntax should be able to cause a crash. Can somebody, possibly explain?

var raw, symbol, obj;

System.println("");
System.println("START TEST STRINGS");
raw = Rez.Strings.AppName;
obj = Rez.Strings;
symbol = :AppName;
if(obj has symbol) {
    System.println("has symbol "+symbol);
    System.println("get "+Rez.Strings[symbol]+" should equal "+raw);
}

System.println("");
System.println("START TEST SENSOR");
raw = Toybox.Sensor.SENSOR_HEARTRATE;
obj = Toybox.Sensor;
symbol = :SENSOR_HEARTRATE;
if(obj has symbol) {
    System.println("has symbol "+symbol);
    System.println("get "+Toybox.Sensor[symbol]+" should equal "+raw);
}

Gets:

START TEST STRINGS
has symbol symbol (24)
get 1550 should equal 1550

START TEST SENSOR
has symbol symbol (8388954)

Error: Unhandled Exception
Exception: UnexpectedTypeException: Expected Object/Array/Dictionary/ByteArray, given Primitive Module
Stack: 

I had thought both of them should work.

Thanks,

G

  • Unfortunately, afaik you can't use bracket notation (`[]`) to access arbitrary members of modules in the way you're trying to do with the second example. Toyboy.Sensor is a module, which explains the crash.

    If "symbol" referred to a method, you would have a way of calling it, but since it refers to an enum, I don't think you can "dereference" it in the way you're trying to.

    I totally get why you'd expect to be able to, tho.

    It works in the first case because Rez.Strings is a dictionary.

  • If "symbol" referred to a method, you would have a way of calling it, but since it refers to an enum, I don't think you can "dereference" it in the way you're trying to.

    Hmm.

    I mean... the practical evidence is in your favour that I can't refer to a module's constant in that way, but... you can with basically everything else... I've expanded my test to include enum, property and...

        var raw, symbol, obj;
    
        System.println("");
        System.println("START TEST STRINGS");
        raw = Rez.Strings.AppName;
        obj = Rez.Strings;
        symbol = :AppName;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+Rez.Strings[symbol]+" should equal "+raw);
        }
    
    
        System.println("");
        System.println("START TEST THIS METHOD");
        raw = self.onLayout;
        obj = self;
        symbol = :onLayout;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+self[symbol]+" should equal "+raw);
        }
    
        System.println("");
        System.println("START TEST THIS PROPERTY");
        raw = self.aValue;
        obj = self;
        symbol = :aValue;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+self[symbol]+" should equal "+raw);
        }
    
        System.println("");
        System.println("START TEST THIS ENUM");
        raw = self.AN_ENUM;
        obj = self;
        symbol = :AN_ENUM;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+self[symbol]+" should equal "+raw);
        }
    
    
        System.println("");
        System.println("START TEST STATIC VAR");
        raw = TestHr_F3View.staticBob;
        obj = TestHr_F3View;
        symbol = :staticBob;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+self[symbol]+" should equal "+raw);
        }
    
        System.println("");
        System.println("START TEST SENSOR");
        raw = Toybox.Sensor.SENSOR_HEARTRATE;
        obj = Toybox.Sensor;
        symbol = :SENSOR_HEARTRATE;
        if(obj has symbol) {
            System.println("has symbol "+symbol);
            System.println("get "+Toybox.Sensor[symbol]+" should equal "+raw);
        }
    

    Gets...

    START TEST STRINGS
    has symbol symbol (25)
    get 1550 should equal 1550
    
    START TEST THIS METHOD
    has symbol symbol (8389122)
    get method should equal method
    
    START TEST THIS PROPERTY
    has symbol symbol (42)
    get something should equal something
    
    START TEST THIS ENUM
    has symbol symbol (41)
    get 0 should equal 0
    
    START TEST STATIC VAR
    has symbol symbol (56)
    get bob should equal bob
    
    START TEST SENSOR
    has symbol symbol (8388954)
    
    Error: Unhandled Exception
    Exception: UnexpectedTypeException: Expected Object/Array/Dictionary/ByteArray, given Primitive Module
    Stack: 

  • Ah!

    I've noticed something - I had self[symbol] rather than obj[symbol] in the above for the static one.

    When I used the obj (class definition) I got an error.

    So it could be that there is simply no object to read in a module.

    Not intuitive, but probably defensible.

  • Primitive modules are 'special'. This is just one of the things that you cannot do with them.