class Foo
a: ->
x.call =>
super
will not compile as I can't call super from anonymous class. However my intention is to call the superclass method for 'a'. Is this a missing capability in coffeescript?
Note that I change the code to
class Foo
a: ->
x.call =>
return Foo.__super__.a.apply(this, arguments)
to make it work but that just ain't coffeescript right!
Your proposed solution of writing out Foo.__super__.a.apply(this, arguments)
is, I'm afraid, basically as good as you're going to get. CoffeeScript allows you to write things like
a = ->
b = ->
super
(in which case super
points to b
's super function), so it would be a bit confusing to have super
within
a: ->
x =>
super
point to a
's super function. You could raise an issue to ask for this to be allowed, though. It's not ambiguous from a compilation standpoint, just a bit odd-looking.
Here's something you could try to be a little more elegant:
class Foo
constructor: ->
@sup = Foo.__super__
a: ->
x =>
@sup.a.apply this, arguments
I've encountered the same problem and solved it like this:
ChainSuper = (classType, memberName, useFatArrow) ->
original = classType::[memberName]
superf = classType.__super__.constructor.prototype[memberName]
callSuper = (thisRef, args, superArgs) ->
for i in [0...superArgs.length]
args[i] = superArgs[i]
superf.apply thisRef, args
classType::[memberName] = if useFatArrow
(args...) ->
original.call @, args..., (superArgs...) =>
callSuper @, args, superArgs
else
(args...) ->
original.call @, args..., (thisRef, superArgs...) ->
callSuper thisRef, args, superArgs
This is very non-kosher and will probably break if the Coffeescript compiler's class semantics change. While waiting for that, however, I'm able to say:
CheckSuper = (ref, message) ->
if ref instanceof Superclass
alert "Works with #{message}"
class Superclass
plus: (values...) ->
CheckSuper @, 'plus'
@val = 0
for i in values
@val += i
alert @val
minusBase: 0
minus: (values...) ->
CheckSuper @, 'minus'
@val = @minusBase
for i in values
@val -= i
alert @val
class Subclass extends Superclass
plus: (values..., Super) ->
setTimeout (=> Super @), 0
ChainSuper @, 'plus'
minus: (values..., Super) =>
@minusBase = values[0]
setTimeout (-> Super values[1...]..., 0), 0
ChainSuper @, 'minus', true
subInstance = new Subclass()
subInstance.plus 1, 2, 3, 4
minus = subInstance.minus
minus 100, 10, 1
Please notice, that with this solution, if you pass n arguments to a Super() when the method has been called with more than n arguments, only the first n arguments get overwritten in the call to the super method and the rest will be passed on unchanged.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With