Skip to content

Class variables generation problem #630

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

Open
faerot opened this issue May 8, 2019 · 3 comments
Open

Class variables generation problem #630

faerot opened this issue May 8, 2019 · 3 comments

Comments

@faerot
Copy link

faerot commented May 8, 2019

when declaring class variable:

class A(B):
    X = 1
    Y = X + 1

transcrypt compiles this into object of properties:

var A = __class__ ('A', [B], {
    __module__: __name__,
    X: 1,
    Y: X + 1,

Which naturally leads to error. You need to adjust class generation mechanics.

@AlexECX
Copy link

AlexECX commented May 8, 2019

I guess replacing the object literal with an anonymous function would do the job.

Maybe have transcrypt compile to this:

var A = __class__ ('A', [B], (function(){
        let o = {};
	o.__module__ = __name__;
	o.X = 1;
        o.Y = o.X + 2;
        return o;
    })());

but that would also make getters more verbose. Example with method that returns self.X:
(EDIT: This is not working, the new property is not picked up by for-in loops)

var A = __class__ ('A', [B], (function(){
        let o = {};
	o.__module__ = __name__;
	Object.defineProperty(o, 'someFunctionName', { get: function() { return __get__ (this, function (self) {
		return self.X;
	});}});
        return o;
    })());

@AlexECX
Copy link

AlexECX commented May 10, 2019

This seems to be working pretty well. Haven't looked into the python transpile code yet, might give it a try sometime.

Example.py

class B:
    pass

class A(B):
    X = 1
    Y = X + 2
    def test(self):
        return self.X

transcrypt.org js


// ^older code
export var __def_method__ = function (obj, method, recurence_name) {
	var method_name = (recurence_name ? recurence_name : method.name);
	Object.defineProperty (obj, method_name, {'get': (function __lambda__ () {
		return __get__ (this, method);
	}), 'set': (function __lambda__ (func) {
		return __def_method__ (this, func, method_name);
	}), 'configurable': true, 'enumerable': true});
};

Example.js

//...
export var B =  __class__ ('B', [object], function(){
    let cls = {}; 
    cls.__module__ = __name__,
    return cls;
}());
export var A = __class__ ('A', [B], function(){
    let cls = {}; 
    cls.__module__ = __name__;
    cls.X = 1;
    cls.Y = cls.X + 2;
    __def_method__(cls, function test(self){
        return self.X;
    });
    return cls;
}());

Performance for class declaration, object instantiation and method calls are the same, the memory profile seems to be the same. It also allows method redefinition of instances.

some more in-depth testing

@AlexECX
Copy link

AlexECX commented May 11, 2019

A simpler, closer to current transcrypt and probably easier to implement version:

transcrypt.org js

export var __def__ = function (obj, method, recurence_name) {
	var method_name = (recurence_name ? recurence_name : method.name);
	Object.defineProperty (obj, method_name, {
        'get': method, 
        'set': (function __lambda__ (func) { 
            return __def__ (this, func, method_name); 
        }), 'configurable': true, 'enumerable': true
    });
};

Examplse.js

//...
export var B =  __class__ ('B', [object], function(){
    let cls = {}; 
    cls.__module__ = __name__,
    return cls;
}());
export var A = __class__ ('A', [B], function(){
    let cls = {}; 
    cls.__module__ = __name__;
    cls.X = 1;
    cls.Y = cls.X + 2;
    __def__(cls, function test() { return __get__ (this, function (self) {
	return self.X;
    });});
    return cls;
}());

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

No branches or pull requests

3 participants