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

Override order is reversed when providing functions instead of Objects #20

Open
kafoso opened this issue Jul 9, 2015 · 6 comments
Open

Comments

@kafoso
Copy link

kafoso commented Jul 9, 2015

In test.js, exports.testOverride verifies that the "youngest" Object (or "class") overrides the same-name function of its parent (or "base"). This test of course works.

However, if the prop argument is a function, the override order is reversed. See example below.

exports.testOverrideOfFunctions = function(test) {
    test.expect(2);
    var A = inherit(function(){
      this.method = function() {
          return 'A';
      };
    });
    var B = inherit(A, function(){
      this.method = function() {
          return 'B';
      };
    });

    test.equal(new A().method(), 'A');
    test.equal(new B().method(), 'B');
    test.done();
};

The above test fails. See output below.

✖ testOverrideOfFunctions

AssertionError: 'B' == 'A'
    at Object.equal (/usr/local/lib/node_modules/nodeunit/lib/types.js:83:39)
    at Object.exports.testOverrideOfFunctions (/home/kafoso/git/inherit/test/test.js:142:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/nodeunit/lib/core.js:236:16)
    at /usr/local/lib/node_modules/nodeunit/lib/core.js:236:16
    at Object.exports.runTest (/usr/local/lib/node_modules/nodeunit/lib/core.js:70:9)
    at /usr/local/lib/node_modules/nodeunit/lib/core.js:118:25
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:513:13
    at iterate (/usr/local/lib/node_modules/nodeunit/deps/async.js:123:13)
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:134:25
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:515:17

Naturally, the prop argument should be an Object per your documentation. However, it would be a nice addition.

@dfilatov
Copy link
Owner

dfilatov commented Jul 9, 2015

What's the case you need to pass Function instead of Object?

@kafoso
Copy link
Author

kafoso commented Jul 9, 2015

@dfilatov
To allow for private variables (or "scope-only" variables) inside the functions. Example:

exports.testInheritedFunctionsWithPrivateVariables = function(test) {
    test.expect(2);
    var A = inherit(function(){
      var _privateVariable = 1;
      this.method = function() {
          return _privateVariable+2;
      };
    });
    var B = inherit(A, function(){
      var _privateVariable = 9;
      this.method = function() {
          return _privateVariable+2;
      };
    });

    test.equal(new A().method(), 3); // Works
    test.equal(new B().method(), 11); // Throws up
    test.done();
};

Output:

✖ testInheritedFunctionsWithPrivateVariables

AssertionError: 3 == 11
    at Object.equal (/usr/local/lib/node_modules/nodeunit/lib/types.js:83:39)
    at Object.exports.testInheritedFunctionsWithPrivateVariables (/home/kafoso/git/inherit/test/test.js:145:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/nodeunit/lib/core.js:236:16)
    at /usr/local/lib/node_modules/nodeunit/lib/core.js:236:16
    at Object.exports.runTest (/usr/local/lib/node_modules/nodeunit/lib/core.js:70:9)
    at /usr/local/lib/node_modules/nodeunit/lib/core.js:118:25
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:513:13
    at iterate (/usr/local/lib/node_modules/nodeunit/deps/async.js:123:13)
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:134:25
    at /usr/local/lib/node_modules/nodeunit/deps/async.js:515:17

@qfox
Copy link

qfox commented Jan 22, 2016

@kafoso You still can do this with __constructor property, isn't it?

exports.testInheritedFunctionsWithPrivateVariables = function(test) {
    test.expect(2);
    var A = inherit(function(){
      var _privateVariable = 1;
      this.method = function() {
          return _privateVariable+2;
      };
    });
    var B = inherit(A, { __constructor: function(){
      this.__base.apply(this, arguments);
      var _privateVariable = 9;
      this.method = function() {
          return _privateVariable+2;
      };
    }});

    test.equal(new A().method(), 3); // Works
    test.equal(new B().method(), 11); // Should also works as expected
    test.done();
};

@qfox
Copy link

qfox commented Jan 22, 2016

@dfilatov Do we want this behaviour as a sugar?

@dfilatov
Copy link
Owner

I don't think so. I still don't understand what a sugar is.

@kafoso
Copy link
Author

kafoso commented Feb 19, 2016

You still can do this with __constructor property, isn't it?

The variable is only available within the constructor's function scope, then. What I'm asking for is private variables, which are available in every function within the "class" Object, but inaccessible from the outside. Entirely like visibility keywords work in PHP, Java and many other high-level programming languages.

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

3 participants