2

This works :

class Foo 
  class @_Bar 
    @narf = ''
    @point : ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point : ->
      @narf = 'woo'
      super()

This does not

class Foo 
  class @_Bar 
    @narf = ''
    @point = ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point = ->
      @narf = 'woo'
      super()

running Foo._Baz.point() will throw and error.


Please someone explain what is going on here.

2
  • In addition to the bug report that Trevor created, github.com/jashkenas/coffee-script/issues/1598 is the issue that added super support to static methods (some 2 years ago). Commented Nov 10, 2013 at 20:30
  • Participating there now. Thanks. Commented Nov 10, 2013 at 20:46

3 Answers 3

3

It seems like a bug in the compiler to me. Writing

class X
  @classMethod: ->

and

class X
  @classMethod = ->

should be equivalent, yet super compiles differently across the two methods. In the first, it compiles correctly:

X.__super__.constructor.classMethod.apply(this, arguments);

In the second, it compiles as if classMethod were an instance method:

X.__super__.classMethod.apply(this, arguments);
Sign up to request clarification or add additional context in comments.

1 Comment

Really, you think its a bug? I thought is was deliberate, and that I was simply not understanding the intent.
2

This works:

class Foo 
  class @_Bar 
    @narf = ''
    point : ->
      @narf = 'what'

  class @_Baz extends @_Bar 
    @point = ->
      @narf = 'woo'
      super()

alert Foo._Baz.point()  # 'what'
alert new Foo._Bar().point() # 'what'

That is, the compiled @point= super ends up pointing to the instance point:. Its JS is: _Baz.__super__.point.call(this), which is _Bar.prototype.point.call(this). (extends defines: child.__super__ = parent.prototype).

It's clear from past Coffeescript changes that @point: is the intended syntax for static (class) methods (and used that way in the compiler itself).

7 Comments

That makes no sense. point : -> attaches as Foo.prototype.point so the static method does not access it.
Try it. I'm pointing out what Coffeescript does, not I think it should do.
Actually point : -> attaches as Foo._Bar.prototype.point.
you are right Foo._Bar.prototype.point is the place it attaches, but your answer " That is, the @point= super points to point: " is still wrong because prototype is not static, its instance.
Your original code throws an error because Foo._Bar.prototype.point is undefined. Mine works because that 'instance' method is defined. The crossover between static to instance is not what you intended, but that is, in effect, what the Javascript code does.
|
1
+50

There are a couple of fixes now on github. https://github.com/jashkenas/coffee-script/issues/3232

Currently the node tree for a @foo= method is different from that of a @foo: method. Because of that, a node created with = is never passed to the Class addParameters method, and is never flagged as static.

One solution, which will probably be accepted, makes sure both forms produce the same node tree.

The one I contributed https://github.com/jashkenas/coffee-script/issues/3232#issuecomment-28316501 adds a method to nodes.coffee class Class. This method is a stripped down version of addParameters, and specifically checks a = node tree.

If you need a fix in your own Coffee compiler, modify your src/coffee-script/nodes.coffee file, compile it, and put the resulting node.js in the lib directory (or use the cake build).

1 Comment

github.com/jashkenas/coffee-script/pull/3237/files is the current modification. The part involving looksStatic can be added to the 1.6.3 nodes.coffee. I haven't played with the part involving METHOD_DEF which addresses a different issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.