Reputation: 30015
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.
Upvotes: 2
Views: 227
Reputation: 231385
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
).
Upvotes: 1
Reputation: 231385
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).
Upvotes: 2
Reputation: 77416
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);
Upvotes: 3