• ...Ic what you mean you follow...

    As you have seen the example of module and the example of use in my previous post, I do now what the instructions for test say. In a nutshell, it is emulating the way the module gets accessed. All code, application AND module are in the same code that is uploaded. Here it goes.

    // to emulate module access for local, inline testing
    var exports = {};
    
    // begin module code
    function TestLED(pin) {
      this.pin = pin;
      pinMode(this.pin,"output");
      this.off();
    };
    TestLED.prototype.on = function() {
        this.pin.set();
    };
    TestLED.prototype.off = function() {
        this.pin.reset()
    };
    exports = TestLED;
    };
    // end module code
    
    
    // begin application code
    // --- var TestLED = require("TestLED"); // require(... replaced w/ line below for module inline testing
    var TestLED = exports; // instead of require, directly access what the module definition exports
    var testLED1pin = B3;
    var testLED1 = new TestLED(testLED1pin);
    setInterval(function(){
      testLed1.on();
      setTimeout(function(){
        testLED1.off();
      },500)
    },1000);
    

    My style is always getting the module into a variable, and then using it from there, since it is a class or some object... more the object-oriented (oo) way. Most example do the other way - for various but not needed reasons: They do the require(... and cascade the function or method all on it right away... more... more the function - and JS basic - way. Separating helps with testing... less code is different from final way.

    Your first example is kind of a mix of both and messes with your exports anyway. So decide for one. The functional approach is like the example describes an your second approach in your first example, where you expose a plain function that calls the new on the class method and return an object. Most modules work this way because there is a connect(... required that creates and returns the connection object through which you access the periphery / sensor / display.

    Initially, assigning a constructor as class was not working... and since even my first Espruino tries were using a class (constructor funtion) rather than a plain function that hides oo. The thing returned from requre(... did not understand new (Espruino intrepreter's new could not apply new on an object returned from require(...).

    I asked then @Gordon to remove the restriction/enable exports to be a class (constructor function) and he changed Espruino right away. Now more and more modules show as classes. It is kind of more natural, because you do not want to think that you are talking to a connection object, which is a technical thing that hides the real object. You want to talk to the sensor object or what directly... so the class that is built models the sensor... You can read up in these conversations. That all started 4+ years ago:

    Until the oo/class-way was available, I had to build the module a bit funny: esxport a function that returned me the class / constructor function... and it worked but required extra code, like I demonstrate here - module code and application code (as final):

    Module code:

    function TestLED(pin) {
      this.pin = pin;
      pinMode(this.pin,"output");
      this.off();
    };
    TestLED.prototype.on = function() {
        this.pin.set();
    };
    TestLED.prototype.off = function() {
        this.pin.reset()
    };
    
    exports.getClass = function(){
        return TestLED; // returning the constructor 'functio'
      };
    

    Application code:

    var TestLED = require("TestLED").getClass(); // to get the constructor 'function'
    var testLED1pin = B3;
    var testLED1 = new TestLED(testLED1pin);
    setInterval(function(){
      testLed1.on();
      setTimeout(function(){
        testLED1.off();
      },500)
    },1000);
    

    Functionally, there is no real difference... but the oo way looks more straight forward - at least to me, especially when you can have multiple instances of something like a sensor, testLED, etc. (Some modules are built the way that multiple instances cannot exist, because not all instance variables are in the object, but rather just in the module on level . They survive garbage collect only because of being referenced directly or indirectly by exposed variables (functions / data objects), which is by the way how to create private state and behavior in JavaScrpt. So watch out for that... it is the same thing with hidden initializations, which should not happen on load of the module but on construction of the instance object.

    Last paragraphs deal with things not really of your concern at hand and I hope it did not confuse more - or only temporarily a bit - but in the end are useful to know and apply to end up with better systems.

About

Avatar for allObjects @allObjects started