Skip to content

Instantly share code, notes, and snippets.

@robfletcher
Created September 15, 2015 01:06
Show Gist options
  • Select an option

  • Save robfletcher/10afa919d71f0a9836ed to your computer and use it in GitHub Desktop.

Select an option

Save robfletcher/10afa919d71f0a9836ed to your computer and use it in GitHub Desktop.
Using companion object apply method from outside of Scala
apply plugin: "groovy"
apply plugin: "scala"
repositories {
jcenter()
}
dependencies {
compile "org.scala-lang:scala-library:2.11.7"
testCompile "org.spockframework:spock-core:1.0-groovy-2.4"
}
package example
import java.time._
case class Event(description: String, time: Option[ZonedDateTime])
object Event {
def apply(description: String) = new Event(description, None)
def apply(description: String, time: ZonedDateTime) = new Event(description, Some(time))
}
package example
import spock.lang.*
import java.time.*
import static scala.None$.MODULE$ as None
import static scala.Some$.MODULE$ as Some
class EventSpec extends Specification {
def "can create an event using primary constructor"() {
given:
def event = new Event("go for a run", Some.apply(ZonedDateTime.now()))
expect:
event.description == "go for a run"
event.time.isDefined()
}
def "can create an event using apply method from companion object"() {
given:
// new Event results in "could not find matching constructor"
// can't use import alias as it would clash with class name
def event = Event$.MODULE$.apply("go for a drink")
expect:
event.description == "go for a drink"
event.time.isEmpty()
}
}
@marc0der
Copy link
Copy Markdown

Mine seems to work fine, although I had to tweak the tests a bit. For me it seems better not to use the default constructor (no new keyword) at all, but always use one of the apply() methods. I don't seem to need the weird MODULE$ imports at all. Here is what my tests look like without change to the Event model itself.

class EventSpec extends Specification {
    def "can create an event using primary constructor"() {
        given:
        def event = Event.apply("go for a run", Some.apply(ZonedDateTime.now()))

        expect:
        event.description == "go for a run"
        event.time.isDefined()
    }

    def "can create an event using apply method from companion object"() {
        given:
        def event = Event.apply("go for a drink")

        expect:
        event.description == "go for a drink"
        event.time.isEmpty()
    }
}

Hope I haven't misunderstood the problem...

@marc0der
Copy link
Copy Markdown

So I looked again this morning, and this compiles fine (without the MODULE$ references). This is using new and apply().

import scala.Some
import spock.lang.*
import java.time.*

class EventSpec extends Specification {
    def "can create an event using primary constructor"() {
        given:
        def event = new Event("go for a run", Some.apply(ZonedDateTime.now()))

        expect:
        event.description == "go for a run"
        event.time.isDefined()
    }

    def "can create an event using apply method from companion object"() {
        given:
        def event = Event.apply("go for a drink")

        expect:
        event.description == "go for a drink"
        event.time.isEmpty()
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment