How do I check for the class of an object in a mocha spec in Coffeescript?
I have tried the following:
# foo.coffee
class Foo
module.exports = new Foo()
# foo_spec.coffee
should = require 'should'
{ Foo } = require 'foo'
foo = new Foo
foo.should.be.an.instanceOf(Foo)
However, I receive ReferenceError Foo is not defined
I believe this to be the easiest approach:
# foo.coffee
class Foo
module.exports = new Foo()
module.exports.Foo = Foo # IMPORTANT, exports the actual class Foo
# foo_spec.coffee
should = require 'should'
{ Foo } = require 'foo' # Requires said class Foo
foo = new Foo
foo.should.be.an.instanceOf(Foo)
Related
You would think a class named "Foo" would actually be named "Foo", but apparently not:
class Foo {
val bar = 5
val name = this.getClass.getName
def pkg = this.getClass.getPackage.getName
}
val q = new Foo()
println(s"The name is ${q.name}")
However, it is not:
defined class Foo
q: Foo = Foo#31e64c64
The name is $line111.$read$$iw$$iw$Foo
Can anyone explain what the IntelliJ Scala Worksheet is doing here?
(And if you were wondering, pkg: String = $line111)
It looks like the Worksheet uses a similar approach to the Scala REPL, namely to wrap each line into a separate, nested object.
The reason this is done this way, is that by the standard Scala semantics, a lot of things you would want to do in a REPL / Worksheet would be illegal. For example, you want to redefine a class when you realize you made a mistake:
class Foo {
def baR(x: Int) = x
}
// Oops! Typo.
class Foo {
def bar(x: Int) = x
}
// error: Foo is already defined as class Foo
// class Foo {
// ^
If the REPL or Worksheet had the same semantics as Scala, you wouldn't be able to fix typos, redefine vals, etc. Therefore, the code is instead compiled as if each line / declaration were a separate object, with some clever nesting, and importing.
The question is what do I need to do to replicate the functionality (for other class cooked on my own) of the scala enumerations:
val MY_ENUM_1, MY_ENUM_2 = Value
this creates 2 instances of Value. How can I do this for something like:
object App extends App {
class Foo {}
val foo1, foo2 = Foo
}
You need to add the new keyword:
scala> class Foo
defined class Foo
scala> val foo1, foo2 = new Foo
foo1: Foo = Foo#470e2030
foo2: Foo = Foo#3fb4f649
val MY_ENUM_1, MY_ENUM_2 = Value
works because it actually calls the method Value from Enumeration, which is:
/** Creates a fresh value, part of this enumeration. */
protected final def Value: Value = Value(nextId)
which will end up calling
protected final def Value(i: Int, name: String): Value = new Val(i, name)
which in turn will return a Val (and also increment nextId).
You can see the whole process in the source code of Enumeration (starts line #128, the Val class is defined line #209).
say I have the following code:
package my
class Foo
class Bar extends Foo
object Chooser {
val isFoo = true
}
I import Foo as:
import my.{Foo => MyClass}
I want to be able to do something like:
If Chooser.isFoo, then:
import my.{Foo => MyClass}
else:
import my.{Bar => MyClass}
I have used Foo in my code as something like this:
object MyObj {
val a = new MyClass
// ...
}
Are there any hidden features of Scala that let me use Bar in place of Foo without modifying the code of MyObj at all. Also what would be the best way to design such code in future so that such extensions are easy?
There isn't but I'm guessing you are more interested in different implementations at runtime than in conditional type import. Your Chooser.isFoo sounds like something that happens during runtime and not in the type system.
One example of how you could do it, since the common type for Foo and Bar is Foo:
val a: Foo =
if (Chooser.isFoo) new my.Foo
else new my.Bar
Edit based on your edit: you could delay the choice by having an abstract type or a type parameter, like so:
class MyObj[T :> Foo] {
val a: T
}
val anInstance = new MyObj[Foo]
val anotherInstance = new MyObj[Bar]
Note the type bound that says that T must be a subclass of Foo, or else you wouldn't know anything about what you can do with a T.
Happen to see this old post & a little curious why it can't do conditional imports in Scala? Maybe old version limit, not sure? But see this, we can import in any place of scala code.
For your scenario, it could be:
try.scala:
package my
class Foo {
}
class Bar extends Foo
object Chooser {
val isFoo = true
}
object MyObj extends App {
if (Chooser.isFoo) {
import my.{Foo => MyClass}
val a = new MyClass
println(a)
} else {
import my.{Bar => MyClass}
val a = new MyClass
println(a)
}
}
run output:
C:\abc\abc>scalac try.scala
C:\abc\abc>scala my.MyObj
my.Foo#6f4a47c7
Are there public instance variables anymore in Scala? I'm reading Programming in Scala, which covers Scala 2.8. If I'm understanding it correctly, it claims that vars in 2.8 are by default public.
I'm trying to write code for 2.9.1.final now, and instance variables are now by default private? But there's no public keyword that I'm aware of. (Interestingly enough, it appears it used to exist sometime in the 2.x series, but it mysteriously disappeared somewhere along the line.)
Am I missing something obvious?
Also, by extension, is there an easy way to declare a variable passed to a class constructor to be public (since it appears that those also have default private visibility now too)?
Example:
class Instance(label: String, attributes: Array[Int]){
val f = 0
}
Eclipse claims that label, attributes, and f are all private. Scala 2.9.1.final is being used as the library.
In scala, if you omit the modifer, then instance fields are public by default:
scala> class Foo { var foo = 1 }
defined class Foo
scala> class Bar { def bar() = { val f = new Foo; f.foo = 5; }}
defined class Bar
No worries there. However, when you use a variable in a constructor, the variable is not necessarily turned into a field:
scala> class Foo(foo: Int)
defined class Foo
scala> class Bar { def bar() = { val f = new Foo(5); println(f.foo) }}
<console>:8: error: value foo is not a member of Foo
class Bar { def bar() = { val f = new Foo(5); println(f.foo) }}
^
so you can declare it as a val or var to have it available:
scala> class Foo(val foo: Int)
defined class Foo
scala> class Bar { def bar() = { val f = new Foo(5); println(f.foo) }}
defined class Bar
Note that all fields are actually private, but scala exposes accessor methods (foo() and foo_=(t: Int)) to enable you to access the fields), which is why scala-ide says that the fields are private (assuming you mean when you hover over the variable).
I have a scala syntax question - say I have a simple dependency pattern construct like the following
trait Master {
val foobar
object SubObject extends SubObject {
foobar = foobar
}
}
trait SubObject {
val foobar
}
Obviously, this will not compile, since the reference
foobar = foobar
is ambiguous.
How do I specify that the RHS of the expression should reference Master's foobar variable? Is there some sort of special usage of 'this' or 'self' that I should know about?
You can use the Master.this qualifier to specifically reference the outer scope, something like the following:
trait Master {
val foobar = "Hello world"
object SubObject extends SubObject {
val foobar = Master.this.foobar
}
}
trait SubObject {
val foobar:String
}
I believe the easiest way is to use a self-type definition. In addition to a bunch of cool type-theoretic effects, you can use a self-type to create an alias for "this". (Haven't tested this)
trait Master {
master =>
val foobar
object SubObject extends SubObject {
foobar = master.foobar
}
}
trait SubObject {
val foobar
}