Search code examples
transcrypt

Transcrypt: Inherit from a JS prototype?


Is there any way to inherit a Transcrypt class from a JS prototype? I've got a JS object type that has a fairly heavy set of functionality I need to preserve, but I'd like to extend it with a lot of the nice affordances in a Transcrypt class (in particular, I'd like to supplement clunky JS math functions with Transcript operator overloads).

I've tried the obvious:

class MyClass (MyJSClass):
    ....

But that doesn't work because the JS class doesn't have Transcrypt's "magic methods".

I've also tried adding methods to the JS prototype:

def add_repr(orig):
    def v_repr(self):
        return "(inherited JS Object)"
    orig.prototype.__repr__ = v_repr

add_repr(MyJSClass)

print (__new__(MyJSClass()))

but in that case the the repr never gets called because Transcrypt is looking for other magic methods or identifiers and doesn't find them so it doesn't go looking for repr

Has anybody worked out a method for either retroactively turning a JS prototype into a Transcrypt class or for inheriting a Transcrypt class from a JS prototype?


Solution

  • As you have noticed, Transcrypt classes differ internally from JavaScript classes, due to the support for multiple inheritance and bound function assignment.

    A clean solution is to make a Transcrypt facade class, that encapsulates the corresponding JavaScript class.

    So to make Transcrypt class Y_tr (and other classes) inherit from JavaScript class X_js, define a Transcrypt class X_tr with an object x_js of class X_js as it's sole attribute (created by X_tr.__init__). You can then have Y_tr inherit from X_tr instead of from X_js.

    Say X_js has methods m_a and m_b, then give X_tr also methods by that name. Method X_tr.m_a just calls x_js.m_a and X_tr.m_b just calls x_js.m_b, returning the respective results.

    Attributes of x_js can be accessed via properties of X_tr having the same name.

    Note that X_tr and Y_tr can be instantiated without using __new__, since self.x_js = __new__ (X_js ())is done in X_tr.__init__.