Skip to content

Class variables generation problem #630

Open

Description

@faerot

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.

Activity

  1. AlexECX commented on May 8, 2019

    @AlexECX

    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;
        })());
    
  2. AlexECX commented on May 10, 2019

    @AlexECX

    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

  3. AlexECX commented on May 11, 2019

    @AlexECX

    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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions