Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scopes of const/let in 2v13.122 #2215

Closed
halemmerich opened this issue May 31, 2022 · 6 comments
Closed

Scopes of const/let in 2v13.122 #2215

halemmerich opened this issue May 31, 2022 · 6 comments

Comments

@halemmerich
Copy link
Contributor

The weather widget exhibits an
weather.wid.js ReferenceError: ReferenceError: "storage" is not defined error with this firmware version. Changing the globally scoped storage var in the lib.js from const to var fixes this. To get the widget to working without errors, there also needs to be a change from let to var for the expiryTimeout variable.

It seems the access from functions to globally defined const/var variables does not yet work correctly.

@halemmerich
Copy link
Contributor Author

Further experiments show additional variables need changes for full functionality (including Gadgetbridge message parsing).
In lib.js there are const variables B2 and _GB that need to be changed to var.

This is just a workaround, I assume correct solution would be fixing the scope handling.

@gfwilliams
Copy link
Member

It seems the access from functions to globally defined const/var variables does not yet work correctly.

Do you think you could give me some short example code of what's not working that should be?

@gfwilliams
Copy link
Member

This is very likely related to #2207 and http://forum.espruino.com/conversations/376541/

@halemmerich
Copy link
Contributor Author

halemmerich commented Jun 6, 2022

I have done some experiments and found a relatively small example which seems to show this problem:

Upload this as issue2215:

function test(p){
  console.log("Test", p);
}

let variable_let = { test: test };
const variable_const = { test: test };
var variable_var = { test: test };

exports.func_let = function (){
  variable_let.test("let");
};

exports.func_const = function (){
  variable_const.test("const");
};

exports.func_var = function (){
  variable_var.test("var");
};

The following snippets can then be run from RAM:
Working as expected:

require("issue2215").func_var();
require("issue2215").func_const();
require("issue2215").func_let();
()=>{
  var test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

Only func_var() working:

()=>{
  let test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();
()=>{
  const test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

The following is strange to me, this also works:

require("issue2215");
()=>{
  const test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

@halemmerich
Copy link
Contributor Author

Adding the example as cached module does not reproduce the problem:

Modules.addCached("issue2215", function() {
  function test(p){
    console.log("Test", p);
  }

  let variable_let = { test: test };
  const variable_const = { test: test };
  var variable_var = { test: test };

  exports.func_let = function (){
    variable_let.test("let");
  };

  exports.func_const = function (){
    variable_const.test("const");
  };

  exports.func_var = function (){
    variable_var.test("var");
  };
});


()=>{
  const test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

@gfwilliams
Copy link
Member

Thanks - well this is all pretty strange!

More stuff...

This breaks:

()=>{
  const x = 5;  
  var test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

And it'd seem that addCached is effectively like requiring the module first, which is why it fails. Add a const in there and it can fail too:

()=>{
  const x = 5;
  
  Modules.addCached("issue2215", function() {
    function test(p){
      console.log("Test", p);
    }

    let variable_let = { test: test };
    const variable_const = { test: test };
    var variable_var = { test: test };

    exports.func_let = function (){
      variable_let.test("let");
    };

    exports.func_const = function (){
      variable_const.test("const");
    };

    exports.func_var = function (){
      variable_var.test("var");
    };
  });

  var test = require("issue2215");
  test.func_var();
  test.func_let();
  test.func_const();
}();

The issue seems to be that in those cases the const/let are being created in the wrong scope (probably the same one as the first const) - but now I have a self-contained test I should be able to fix it pretty quick - thanks for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants