Skip to content

calling super in methods defined on namespaced classes #1392

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

Closed
michaelficarra opened this issue May 25, 2011 · 2 comments · Fixed by #3785
Closed

calling super in methods defined on namespaced classes #1392

michaelficarra opened this issue May 25, 2011 · 2 comments · Fixed by #3785
Labels

Comments

@michaelficarra
Copy link
Collaborator

C::m = -> super compiles correctly into

C.prototype.m = function() {
  return C.__super__.m.apply(this, arguments);
};

namespaced.C::m = -> super" compiles incorrectly into

namespaced.C.prototype.m = function() {
  return m.__super__.constructor.apply(this, arguments);
};

Proper compilation would have been

var _ref;
_ref = namespaced.C;
_ref.prototype.m = function() {
  return _ref.__super__.constructor.apply(this, arguments);
};

The error originates from the METHOD_DEF regex being used by Assign::compileNode matching only identifiers. Call::superReference is then compiling incorrectly.

@michaelficarra
Copy link
Collaborator Author

Note: the caching I recommend above will protect us from multiple execution in cases such as namespace().C()::m = -> super, but will also have the following effect:

namespace.A::m = (-> super)
namespace.B::m = namespace.A::m
(new namespace.B).m()

will invoke the m method on the superclass of whatever was the value of namespace.A at definition time. @jashkenas: acceptable?

@jashkenas
Copy link
Owner

Yes -- I think that's quite acceptable. Expected, even.

If your class call is a factory that's producing instances of new classes, you'd expect the one you used to define your prototype to also be used when you call super(), not a fresh class object.

lydell added a commit to lydell/coffee-script that referenced this issue Jan 11, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last property is 'prototype':
    A::m = -> super
    A['prototype'].m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
lydell added a commit to lydell/coffee-script that referenced this issue Jan 12, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last property is 'prototype':
    A::m = -> super
    A['prototype'].m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
lydell added a commit to lydell/coffee-script that referenced this issue Jan 14, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last property is 'prototype':
    A::m = -> super
    A['prototype'].m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
lydell added a commit to lydell/coffee-script that referenced this issue Jan 16, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last access is 'prototype':
    A::m = -> super
    A.prototype.m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
lydell added a commit to lydell/coffee-script that referenced this issue Jan 17, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last access is 'prototype':
    A::m = -> super
    A.prototype.m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
lydell added a commit to lydell/coffee-script that referenced this issue Feb 3, 2015
As discussed in jashkenas#3039 (comment).
This is the first step to implement dynamic object literal keys (see jashkenas#3597).

This also fixes jashkenas#1392.

In short, `super` is now allowed:

    # in class definitions:
    class A
      instanceMethod: -> super
      @staticmethod: -> super
      @staticMethod2 = -> super

    # in assignment where the next to last access is 'prototype':
    A::m = -> super
    A.prototype.m = -> super
    a.b()[5]::m = -> super
    A::[x()] = -> super
    class B
      @::m = -> super
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants