Can't decorate a method on a strong class

61 views
Skip to first unread message

Ivan Kozik

unread,
Oct 30, 2015, 10:09:58 AM10/30/15
to Strengthen JS
Hi,

Is there any way to decorate a method on a strong class in V8 4.6?  I have a
lot of code that does `A.prototype.m = Promise.coroutine(A.prototype.m);`
as in this example, sometimes on many methods.

"use strong";

const Promise = require('bluebird');

class A {
    *m() {
        yield new Promise();
    }
}

// TypeError: Cannot assign to read only property 'm' of #<A>
//A.prototype.m = Promise.coroutine(A.prototype.m);

// TypeError: Can't add property mAsync, object is not extensible
//A.prototype.mAsync = Promise.coroutine(A.prototype.m);



In an unfortunate turn of events, the `this` limitations prevent me from
doing it in the constructor as well:

class B {
    constructor() {
        // SyntaxError: In strong mode, 'this' can only be used to
        // initialize properties, and cannot be nested inside another
        // statement or expression
        this.m = Promise.coroutine(this._m);
    }

    *_m() {
        yield new Promise();
    }
}

Of course, I could move *_m() outside of the class to avoid that problem,
but that's getting into silly territory.  m() could have an inner function that
decorates every time, or I could write my own little method cache, but
neither of those seem appealing either.

Thanks,

Ivan

Andreas Rossberg

unread,
Oct 30, 2015, 10:18:31 AM10/30/15
to Ivan Kozik, Strengthen JS
On 30 October 2015 at 15:09, Ivan Kozik <iv...@ludios.org> wrote:
> Is there any way to decorate a method on a strong class in V8 4.6? I have a
> lot of code that does `A.prototype.m = Promise.coroutine(A.prototype.m);`
> as in this example, sometimes on many methods.
>
> "use strong";
>
> const Promise = require('bluebird');
>
> class A {
> *m() {
> yield new Promise();
> }
> }
>
> // TypeError: Cannot assign to read only property 'm' of #<A>
> //A.prototype.m = Promise.coroutine(A.prototype.m);
>
> // TypeError: Can't add property mAsync, object is not extensible
> //A.prototype.mAsync = Promise.coroutine(A.prototype.m);
>
>
> In an unfortunate turn of events, the `this` limitations prevent me from
> doing it in the constructor as well:
>
> class B {
> constructor() {
> // SyntaxError: In strong mode, 'this' can only be used to
> // initialize properties, and cannot be nested inside another
> // statement or expression
> this.m = Promise.coroutine(this._m);
> }
>
> *_m() {
> yield new Promise();
> }
> }

Hi Ivan,

the freezing of class prototypes is rather fundamental to strong mode,
so you won't be able to do that, I'm afraid.

We have, however, decided to drop the `this` restriction for
constructors, so your latter solution should work in the future. Would
that be good enough for your use case?

/Andreas

Ivan Kozik

unread,
Oct 30, 2015, 10:36:54 AM10/30/15
to Andreas Rossberg, Strengthen JS
On Fri, Oct 30, 2015 at 2:18 PM, Andreas Rossberg <ross...@google.com> wrote:
> the freezing of class prototypes is rather fundamental to strong mode,
> so you won't be able to do that, I'm afraid.
>
> We have, however, decided to drop the `this` restriction for
> constructors, so your latter solution should work in the future. Would
> that be good enough for your use case?

Glad to hear it! Yes, I think that would be perfectly fine.

Thanks,

Ivan

Justin Fagnani

unread,
Oct 30, 2015, 7:04:39 PM10/30/15
to Strengthen JS, ross...@google.com


On Friday, October 30, 2015 at 7:36:54 AM UTC-7, Ivan Kozik wrote:
On Fri, Oct 30, 2015 at 2:18 PM, Andreas Rossberg <ross...@google.com> wrote:
> the freezing of class prototypes is rather fundamental to strong mode,
> so you won't be able to do that, I'm afraid.

What about the decorators proposal, would that allow for sufficient freezing, since decorator functions (in some cases) just modify the property descriptor before it's installed?
Reply all
Reply to author
Forward
0 new messages