Under Review
over 1 year ago

Referencing an imported module doesn't run its parent's

If I have a program like:

import Toybox.Application;
import Toybox.System;

class MyApp extends Application.AppBase {

    function initialize() {
        AppBase.initialize();
        System.println(Rez.Strings.AppName);
    }
    ...
}

it prints out a random (well not really) number. It should be a Symbol, but I already filed a bug against that.

But if I import Rez.Strings, it doesn't work:

import Toybox.Application;
import Toybox.System;
import Rez.Strings;

class MyApp extends Application.AppBase {

    function initialize() {
        AppBase.initialize();
        System.println(Strings.AppName);
    }
    ...
}

Now it prints null.

But if I change it to

import Toybox.Application;
import Toybox.System;
import Rez.Strings;

class MyApp extends Application.AppBase {

    function initialize() {
        AppBase.initialize();
        System.println(Strings.AppName);
        var x = Rez;
        System.println(Strings.AppName);
    }
    ...
}

I get null from the first println, and a random number from the second. So reading Rez fixes it.

I think the problem is that the <init> routine for a module runs the first time you mention that module. So if I say Rez.Strings, the init for Rez runs. Similarly, just assigning Rez to a local seems to cause it to run. But going directly for Strings via an import bypasses that, and we get to read uninitialized data (or rather, initialized to null).

My guess is that when getm or getv fetch a module, the runtime checks to see if the module's init has already run, and if not runs it. The bug seems to be that it should first check that any outer module's init has also run.

I've verified the bug with 4.1.5, 4.1.7 and 4.2.0beta2

Parents Comment Children
  • That's why I asked about the background permission and scoping

    Right - because not having the background permission would definitely explain why it works when you use Rez.Strings.MyApp, fails when you say Strings.MyApp *before* mentioning Rez, and works when you say Strings.MyApp after mentioning Rez...