I'm stucked in trying to pass a splat forward to the super constructor. Something like this:
class Mom
constructor: (vars...) ->
[code]
class Son extends Mom
constructor: (vars...) ->
super(???)
[code]
Well, question is:
How do I call the super constructor passing along the son's received splat arguments?
super vars... is probably what you are looking for.
super is super magical.
If you just write super it will compile to a call to the super-constructor forwarding all parameters, which is just what you want in this case :)
class Mom
constructor: (vars...) ->
console.log "constructing Mom with #{vars}"
class Son extends Mom
constructor: (vars...) ->
super
new Son 'a', 'b', 'c'
# Output: constructing Mom with a,b,c
You don't need to do a thing. The constructor actually uses only the arguments javascript variable. And that means, you can leave your call to super just as is.
Related
Lets suppose i have a class A which implements this function:
function do_Some_Thing_With_Points(obj, P)
obj.other_function();
I would like to understand the following use of this function:
Let a be an instance of A and:
a.do_Some_Thing_With_Points(P);
Is it ok to not pass the parameter obj, and what does it mean?
Thanks!
You are actually passing obj, which is in your case a. This is because this
a.do_Some_Thing_With_Points(b);
is equivalent to
do_Some_Thing_With_Points(a, b);
at least if only one instance of the class is provided to the function.
The syntax of the second case is not recommended, since the 'owner' of the method is not provided explicitly (if b would be an instance of class A as well, this method owner is not obvious). I just included it to help you understand where the obj comes from.
class Animal
constructor: (#name) ->
move: (meters) ->
alert #name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
So I was going through the CoffeeScript docs and ran into the above illustration of class extension. Can someone explain to me exactly what is happening when the line super 5 is executed? I vaguely understand it is calling the super class's definition of move with the argument, 5, but what would the output look like if one called mySnake.move assuming my snake's name is Robert?
super will call the move method on the base class. Specifically, it will call the Animal move method and pass in 5 as the meters parameter.
If you run the example on the CoffeeScript page, you should see an alert with "Sammy the Python moved 5m."
super is useful when your subclass has its own logic to run in addition to the base class implementation. You can place super right at the beginning of the method, or after additional code runs. Order might matter depending on the logic that's in place.
In CoffeeScript, I'd like to be able to assign the super method to a variable without calling it.
class a
one: ->
class b extends a
one: ->
mySuper = super
However doing the following actually calls the super method rather than returning it - here's the compiled code:
return mySuper = b.__super__.one.apply(this, arguments);
How do I actually assign the super method to a variable rather than calling it?
I know I could do:
class b extends a
one: ->
mySuper = b.__super__.one
But it isn't that clean.
Coffee script provides no syntax sugar for this use case. So do it yourself.
I would do it like this:
class B extends A
one: ->
mySuper = A::one
mySuper.call this # calls the saved super method
Example
:: is a shorthand for prototype. So A::one compiles to A.prototype.one which is where your super method actually is.
But this seems like a red flag to me. I can't think of a case where this would be a good idea. I'd wager it's not part of the language because if you design your classes properly, you shouldn't need this. You say you want something clean, but the thing you want to do here I wouldn't consider clean at all.
I want to split up a large class by using mixins.
I am using this mixin code from the Little Book
#include: (obj) ->
for key, value of obj when key not in moduleKeywords
# Assign properties to the prototype
#::[key] = value
obj.included?.apply(#)
this
class FooMixin
b: => #something = 2
class Foo extends Module
#include FooMixin
a: => #something = 1
Problem is that # in FooMixin is FooMixin. I want it to be Foo instead.
I have tried adding the line _.bind(#::[key], #) at the end of #include() but it doesn't help. Any suggestions?
Okay, few things I was doing wrong.
1.
#include from the Little Book takes an object not a class. To get it to work with classes you need to write #include FooMixin::. However, I have since begun using objects instead.
2.
When using an object instead of a class, the fat arrow adds a line inside the CoffeeScript wrapper right at the top which reads _this = this. All methods are bound to the global context which is not what we want. To fix we must convert fat arrows to thin arrows, and bind each function to our Foo instance. Using Underscore I added this to the constructor of Foo:
constructor: ->
for fname in _.functions FooMixin
#[fname] = _.bind #[fname], #
super
I tried _.bindAll #, _.functions FooMixin but it gave me an error saying something like At Function.bind, could not run bind of undefined. Weird error, seeing as the code above is pretty much identical to the _.bindAll method.
So now I can split my classes up for better readability and code sharing.
UPDATE: The problem with _.bindAll is that it takes a splat not an array. Fix is to use _.bindAll #, _.functions(FooMixin)....
UPDATE: Found a better solution.
Same as original post. Use classes for mixins.
Use #include FooMixin:: or change #include to operate on a prototype instead of properties.
In the Foo constructor write FooMixin.call # which binds the methods correctly.
This works well and is nice and clean.
The only potential issue is that mixins will be overridden by existing properties. The only way to get around this that I can see is to do something like:
after = ->
_.extend Foo, FooMixin::
class Foo
# define...
after()
Or pass the extend method to _.defer but this is so hacky and probably won't work.
I have a function foo which takes another function (say bar) as a parameter. Is there a way to get the function name of bar as a string inside foo?
No. See the difference between methods and functions. Methods aren't passed as parameters under the hood - they are expanded into function objects when being passed to some other method/function. These function objects are instances of anonymous, compiler-generated classes , and have no name (or, at least, being anonymous classes, have some mangled name which you could access using reflection, but probably don't need).
So, when you do:
def foo() {}
def bar(f: () => Unit) {}
bar(foo)
what actually happens in the last call is:
bar(() => foo())
Theoretically, though, you could find the name of the method that the function object you're being passed is wrapping. You could do bytecode introspection to analyze the body of the apply method of the function object f in method bar above, and conclude based on that what the name of the method is. This is both an approximation and an overkill, however.
I've had quite a dig around, and I don't think that there is. toString on the function object just says eg <function1>, and its class is a synthesised class generated by the compiler rather that something with a method object inside it that you might query.
I guess that if you really needed this there would be nothing to stop you implementing function with something that delegated but also knew the name of the thing to which it was delegating.