I have a CoffeeScipt class defined like such
class Foo
a: 1
b: 2
main: ->
if a == 1
log(1)
log: (num) ->
console.log(num)
f = new Foo
f.main()
it keeps erroring out saying that log is not defined. I tried making it #log: didn't work either. I tried making the -> of main a => and did not work either. How can I call instance methods from within the class itself?
Use # when calling instance methods and fields not when defining:
class Foo
a: 1
b: 2
main: ->
if #a == 1
#log(1)
log: (num) ->
console.log(num)
f = new Foo()
f.main()
Defining methods with # like this
#log: (num) ->
console.log(num)
makes them static.
Look at the compiled JS while developing on CoffeeScript.
Related
For code reuse purpose I want to capture some logic in a single function and have it called in other modules
Here is the function definition
// Module A
define (require) ->
doSomething(a, b, c) ->
"#{a}?#{b}&#{c}"
And here is how the funciton doSomething is used
// Module B
define(require) ->
a = require 'A'
...
class Bee
constructor: ->
#val = a.doSomething(1, 2, 3)
However in the browser, I got this error message
Uncaught ReferenceError: doSomething is not defined
What is the proper way to export/import a free function in coffeescript?
This:
define (require) ->
doSomething(a, b, c) ->
"#{a}?#{b}&#{c}"
isn't a function definition. That is really this in disguise:
define (require) ->
return doSomething(a, b, c)( -> "#{a}?#{b}&#{c}")
so your module is trying to call the doSomething function and then call what it returns as another function which takes a third function as an argument. Then whatever doSomething(...)(...) returns is sent back from the module.
So when you say this:
a = require 'A'
you're getting "who knows what" in a and that thing doesn't have a doSomething property so a.doSomething(1,2,3) gives you a ReferenceError.
I think you want to wrap your function in an object in your module:
define (require) ->
doSomething: (a, b, c) ->
"#{a}?#{b}&#{c}"
Alternatively, you could just return the function:
define (require) ->
(a, b, c) ->
"#{a}?#{b}&#{c}"
and then use it like this:
doSomething = require 'A'
doSomething(1, 2, 3)
I'm writing some widgets for Ubersicht. It uses a node.js server and treats each .coffee file as a standalone widget object. I'm having issues defining constant settings to be used throughout one file. Currently I know of two ways to define this type of constant at the top of the file.
# Way 1
foo_1 = true
bar_1 = false
# Way 2
foo_2: true
bar_2: false
Further down in the same file either a property is assigned as a string or as a function. Each of the above two ways of defining an option only works in one of the two property types.
staticProperty: """Output #{foo_1} works here
but output of #{foo_2} doesn't work
"""
methodProperty: (input) ->
if foo_1 # Raises foo_1 is not defined
if #foo_1 # foo_1 is undefined which is expected
if #foo_2 # This works fine
I understand that way 2 add to the object's properties, but I'm not too sure how the way 1 assignment works given that the file is essentially defining an object. Can you explain this?
Also is there a way to define a variable that can be accessed from both places?
We'll look at a big ugly example to see what's going on:
class C
a: 6
b: #::a
c = 11
d: c
#e = 23
f: #e
g: -> #a
h: -> C::b
i: -> c
j: -> #constructor.e
a is a normal old property, in JavaScript it looks like:
C.prototype.a = 6;
b is also a normal old property that is attached to the prototype; here:
b: #::a
# is the class itself so in JavaScript this is:
C.prototype.b = C.prototype.a
and everything works just fine.
c is sort of a private variable. In JavaScript it looks like this:
var C = (function() {
function C() {}
var c = 11;
//...
})();
I've included more JavaScript context here so that you can see c's scope. c is visible to anything inside the definition of C but nowhere else.
d is another property that is on the prototype and looks like this in JavaScript:
C.prototype.d = c
This assignment happens inside the SIF wrapper that is used to build the class so var c = 11 is visible here.
e is a class property and in JavaScript is just:
C.e = 23;
f is another property on the prototype. # is the class itself in this context (just like in b):
f: #e
so we can get at e as #e and the JavaScript looks like:
C.prototype.f = C.e;
The g and h methods should be pretty clear. The i method works because it is a closure inside the SIF that is used to define C:
C.prototype.i = function() { return c; };
The j method works because it uses the standard constructor property to get back to C itself.
Demo: http://jsfiddle.net/ambiguous/tg8krgh2/
Applying all that to your situation,
class Pancakes
foo_1 = true
foo_2: true
We see that you can use either approach if you reference things properly:
staticProperty: """Output #{foo_1} works here
and so does #{#::foo_2}
"""
methodProperty: (input) ->
# foo_1 should work fine in here.
# #foo_1 is undefined which is expected
# #foo_2 works fine
I'm not sure why you're having a problem referencing foo_1 inside your methodProperty, it should work fine and does work fine with the current version of CoffeeScript.
Demo scala code:
trait A {
val a = 3
val b = a + 2
}
trait B extends A {
override val a = 10
}
object X extends B
println(X.b)
It prints value: 2, why is it not 5 or 12?
To answer the why:
In Scala when you write
class A {
val a = 2
}
The value is initialized in the constructor of the class (the same behavior applies to traits and objects). Furthermore, superclasses are initialized before subclasses. This leads to the following behavior for your use case:
B is created (memory is reserved), with two variables a and b whose value is 0. Now the constructor of A is invoked. Because a is overwritten in a subclass and due to Scalas dynamic binding nature, it is not assigned with 2, but with the value of the subclass. You want to be it 10, but because this assignment happens in the constructor of B (which is not yet invoked) the default value 0 is assigned. Now, b is assigned. Because it is not overwritten, the value a+2 is chosen, where a is 0. Because the constructor of A is finished here, the constructor of B can be invoked, which assigns 10 to a.
Hence, a is 10 and b is 2.
To answer what to do against this behavior bug:
Don't use vals as long as you don't absolutely understand about the problems that can arise. Use defs or lazy vals instead, there values are not initialized in the constructor of a class and therefore can be easily overwritten. If you absolutely need a val in a trait, then make it final
It is possible to mark a var as initialization independent for the subclass, which can be done with var a: Type = _. This tells the compiler to not initialize this variable in the constructor of the defining class (but means that the value needs to stay mutable). It can then easily be assigned in the subclass. This gets important when the in the constructor of the superclass as method is called, that initializes a var:
class A {
f()
def f() = ()
}
class B extends A {
// don't initialize this var with anything else here or
// the later assignment will be overwritten
var b: Int = _
override def f() =
b = 5
}
new B().b // prints 5
I'm trying to get the classOf[the-abstract-class-Option], but instead I always get the classOf[the-Option-*object*]. How can I get the class of the abstract class instead?
Both Option.getClass and classOf[Option[_]] gives me class scala.Option$.
Edit: I needn't have asked this; all of a sudden, classOf[Option[_]] works fine, weird. /Edit
Background:
I'm trying to invoke via reflection a method that takes an Option[String] parameter.
It signature look like so: ...(..., anySectionId: Option[String], ...)...
Before I can invoke the method, I look it up via getDeclaredMethod. But to do that, I need a list of parameter types, which I construct by calling _.getClass on each argument I'm going to give to the method. But _.getClass returns classOf[None] or classOf[Some] for Option instances, which makes getDeclaredMethod fail, because (?) the signature is based on Option not Some/None.
Here's the code:
val clazz: Class[_] = Play.current.classloader.loadClass(className)
val paramTypes = arguments.map(_ match {
case None => Option.getClass // gives me the object, not the abstract class
case _: Some[_] => classOf[Option[_]] // this also gives me the object :-(
case x => x.getClass // results in None or Some for Option instances
})
val m: jl.reflect.Method = clazz.getDeclaredMethod("apply", paramTypes: _*)
and the last line above fails for a method with any Option parameter (otherwise everything works fine).
The best way is use Scala reflection.
The next best way is not to make work for yourself by trying to match the param types.
Using getClass fails for subtypes:
scala> class Foo
defined class Foo
scala> class Bar extends Foo
defined class Bar
scala> class Baz { def baz(f: Foo) = 1 }
defined class Baz
scala> val b = new Baz
b: Baz = Baz#d33eaa9
scala> val p = new Bar
p: Bar = Bar#406c5ca2
scala> classOf[Baz].getDeclaredMethod("baz", p.getClass)
java.lang.NoSuchMethodException: Baz.baz(Bar)
It's easier just to match on the name:
scala> classOf[Baz].getMethods.find(_.getName == "baz") map (_.invoke(b,p)) getOrElse -1
res5: Any = 1
or filter on the number of params for poor man's overloading resolution, then maybe filter on all args having conforming types.
The notation for accidentally getting the object is in fact:
scala> classOf[Option$]
res8: Class[Option$] = class scala.Option$
Answer: classOf[Option[_]]
Weird! Suddenly classOf[Option[_]] works. I feel sure I tested once or twice before I submitted the question :-( Perhaps the IDE didn't have time to save the file before I recompiled, weird.
I don't know if I should delete the question. Or perhaps I should leave it as is, in case classOf[Option[_]] isn't obvious to everyone.
In a fat arrowed function of a coffeescript class, how can I access the scope of the class as well as the function?
Example:
class Example
foo: ->
$('.element').each => # or ->
#bar($(this)) # I want to access 'bar' as well as the jquery element
bar: (element) ->
element.hide()
So in this example, if I use a => then the # refers to the this of the class but the 'this' is then wrong, whereas if I use a -> for the each, then the 'this' is correctly scoped but but then how do I reference the class function bar?
Thanks!
While mak is right, he fails to point out that in coffee script you rarely need jQuery's each method, which as you noticed, punches your execution context in the face without your permission.
class Example
foo: ->
for element in $('.element')
#bar $(element)
bar: (element) ->
element.hide()
Coffee script's looping features support the concept of each without any actual custom library code at all. And they also do not generate a new scope or context meaning you dont need a fat arrow of any kind.
That's because in CoffeeScript # is an alias for this i.e. when you compile your .coffee to .js # will be replaced with this.
If Example::bar is ugly, I don't think there are 'prettier' solutions.
You can store a reference to this before calling .each:
class Example
foo: ->
self = #
$('.element').each ->
self.bar($(this)) # or self.bar($(#))
bar: (element) ->
element.hide()
After checking different solution. Here something appear for me as the most complete sample with each and click :
class MainApp
self = []
constructor: ->
self = #
toDoOnClick: (event) ->
self.bar($(event.target)) #hide the clicked object
bar: (element) ->
element.hide()
sampleMethod:->
$(".myDiv").click (e) -> self.toDoOnClick(e)
$('.element').each ->
self.bar($(this))