`override` overrides nothing, but no error is given - scala

Here's the example:
class A {
def postStop() {
println("A.postStop")
}
}
class B extends A with C {
override def postStop() {
println("B.postStop")
}
}
trait C { this: B =>
override def postStop() { // here I expected a warning
println("C.postStop")
}
}
object Main {
def main(args: Array[String]) {
new A().postStop()
}
}
This code prints B.postStop, and C.postStop override is silently ignored. Why is no warning printed? Is that a bug or a feature?

In this case it's not possible to issue a warning, because the compiler can't be sure that C.postStop() is never invoked. There can be another class defined somewhere, that extends B and C and explicitly calls C.postStop():
class D extends B with C {
override def postStop() {
super[C].postStop()
}
}
And this will invoke C.postStop() when you use it:
scala> D().postStop()
C.postStop

Related

How to stack behaviour with traits extending BeforeAfterAll

I'm in a situtation where I have 2 traits extending BeforeAfterAll doing different actions for integration tests: One managing the database and the other the file system. For example:
trait DBSpecification extends BeforeAfterAll {
override def beforeAll() = {
println("DB -> BeforeAll")
}
override def afterAll() = {
println("DB -> AfterAll")
}
}
trait FileSystemSpecification extends BeforeAfterAll {
override def beforeAll() = {
println("FileSystem -> BeforeAll")
}
override def afterAll() = {
println("FileSystem -> AfterAll")
}
}
class MyTest extends Specification with DBSpecification with FileSystemSpecification {
"some test" in {
1 ==== 1
}
}
If I do like this, only the prints of the last trait are executed, in this case FileSystemSpecification. If I try calling super from the traits, I start having some compilation problems. I've tried already a bunch of ways, but couldn't figure out the solution.
ScalaTest has some examples on its documentation, but couldn't find a way with Specs2.
Any ideas?
Yes traits are not the best thing for composing behaviour. Here is the boilerplaty way to do it:
import org.specs2.mutable._
import org.specs2.specification._
trait DBSpecification extends BeforeAfterAll {
def beforeAll() = {
println("DB -> BeforeAll")
}
def afterAll() = {
println("DB -> AfterAll")
}
}
trait FileSystemSpecification extends BeforeAfterAll {
def beforeAll() = {
println("FileSystem -> BeforeAll")
}
def afterAll() = {
println("FileSystem -> AfterAll")
}
}
trait FileSystemDBSpecification extends DBSpecification with FileSystemSpecification {
override def beforeAll() = {
super[DBSpecification].beforeAll()
super[FileSystemSpecification].beforeAll()
}
override def afterAll() = {
super[DBSpecification].afterAll()
super[FileSystemSpecification].afterAll()
}
}
class MyTestSpec extends Specification with FileSystemDBSpecification {
"some test" in {
1 ==== 1
}
}

Scala: Not able to find implicit from object

I have the following scala code. I don't understand why the implicit is not being figured by the compiler. I also tried putting the import line inside Main. Note however that when the implicit object was created inside Main, then the code ran correctly
import LoggingAddon._
object Main {
def main(args: Array[String]): Unit = {
val dog = new Dog
Util.act(dog)
}
}
class Dog {
def bark(): Unit = {
println("woof")
}
}
trait Action[A] {
def action(x: A): Unit
}
trait WithoutLogging[A] extends Action[A] {
}
trait WithLogging[A] extends Action[A] {
}
object LoggingAddon {
implicit object DogWithLogging extends WithLogging[Dog] {
override def action(x: Dog): Unit = {
println("before")
x.bark()
print("after")
}
}
}
object NoLoggingAddion {
implicit object DogWithoutLogging extends WithoutLogging[Dog] {
override def action(x: Dog): Unit = {
x.bark()
}
}
}
object Util {
def act(x: Dog)(implicit nolog: Action[Dog]): Unit = {
nolog.action(x)
}
}
I have imported the necessary implicit from the LoggingAddon but still the scala compiler says could not find implicit Action[Dog]
All I'm trying to do is make a pluggable typeclass. Rather than changing any piece of code, merely change the import statements to have different side effects
Simply move the order of usage where implicit is imported, I moved to the bottom in following example
class Dog {
def bark(): Unit = {
println("woof")
}
}
trait Action[A] {
def action(x: A): Unit
}
trait WithoutLogging[A] extends Action[A] {
}
trait WithLogging[A] extends Action[A] {
}
object LoggingAddon {
implicit object DogWithLogging extends WithLogging[Dog] {
override def action(x: Dog): Unit = {
println("before")
x.bark()
print("after")
}
}
}
object NoLoggingAddion {
implicit object DogWithoutLogging extends WithoutLogging[Dog] {
override def action(x: Dog): Unit = {
x.bark()
}
}
}
object Util {
def act(x: Dog)(implicit nolog: Action[Dog]): Unit = {
nolog.action(x)
}
}
import LoggingAddon._
object Main {
def main(args: Array[String]): Unit = {
val dog = new Dog
Util.act(dog)
}
}

Scala - call method on upper bounded instance

In the code below, there's a DogSearcher which has a method called fetch that expects a Ball. We could also have a CatSearcher with a fetch method that expected a Bell. The idea is that we can call fetch on an instance that inherits from PetSearcher and provide different arguments to it.
Any idea what I'm missing?
trait PetSearcher {
def search(what: Thing): Unit = {
println("default searching")
}
}
class DogSearcher extends PetSearcher {
def search(what: Ball): Unit = {
println("dog searching")
}
}
trait Thing {
val name: String
}
case class Ball(name: String) extends Thing
class Pet {
def fetch[S <: PetSearcher, F <: Thing](searcher: S, what: F): Unit = {
println(what)
searcher.search(what)
}
}
class Dog extends Pet {
val searcher = new DogSearcher()
val ball = new Ball("red")
def go(): Unit = {
fetch[DogSearcher, Ball](searcher, ball)
}
}
//should use DogSearcher but calls fetch on Search, not on DogSearcher.
// So prints default searching, not dog searching..
new Dog().go()
The search method of DogSearch does not override the search method of PetSearcher because the argument types are different (what is a Thing for PetSearcher but a Ball for DogSearcher - the fact that Ball extends Thing is not enough to make the function calls the same).
Let PetSearcher take a type parameter to define the type of what, then DogSearcher can override this (note the override keyword becomes necessary):
trait PetSearcher[T] {
def search(what: T): Unit = {
println("default searching")
}
}
class DogSearcher extends PetSearcher[Ball] {
override def search(what: Ball): Unit = {
println("dog searching")
}
}
To get it to compile, you also need to update the use of PetSearcher in Pet, by adding the type parameter F (the subtype of Thing that this Pet searches for) to the PetSearcher:
def fetch[S <: PetSearcher[F], F <: Thing](searcher: S, what: F): Unit = {
As an alternative to #JamesThorniley's answer, you could define search to accept anything which extends Thing:
trait PetSearcher {
def search[T <: Thing](what: T): Unit = {
println("default searching")
}
}
class DogSearcher extends PetSearcher {
override def search[T <: Thing](what: T): Unit = {
println("dog searching")
}
}
This outputs dog searching as desired.

Calling the overriden method from a trait with selftype

Suppose, you have a trait with a selftype and you've overriden one of the methods:
trait A {
def foo() { println("A") }
}
trait B { this: A =>
override def foo() {
println("B")
}
}
object Test {
def main (args: Array[String]) {
val b = new A with B {}
b.foo()
}
}
So far so good, it compiles and produces "B" to the output. But how do I call the "shadowed" method from A to do something like this:
trait A {
def foo() { println("Hello, ") }
}
trait B { this: A =>
override def foo() {
//here I'd like to do something like super.foo()
println("world!")
}
}
object Test {
def main (args: Array[String]) {
val b = new A with B {}
b.foo() //Should print "Hello, world!"
}
}
Is it even possible to call overriden foo? Or should I prefer inheritance to selftype to make this possible?
What you are looking for is abstract override, which let you implement the stackable trait pattern.
If you define foo on trait A such as the following
trait A {
def foo()
}
trait M extends A {
abstract override def foo() {println("M"); super.foo()}
}
class FooImpl1 extends A {
override def foo() {println("Impl")}
}
class FooImpl2 extends FooImpl1 with M
Inspired by Edmondo's version:
scala> class C { def c = "C" }
defined class C
scala> trait T1 { def c:String }
defined trait T1
scala> trait T2 extends T1 { self:C =>
| abstract override def c = super.c + " with T2"
|}
defined trait T2
scala> new C with T2
res0: C with T2 = $anon$1#1f841222
scala> res0.c
res1: java.lang.String = C with T2

Is it possible to pass "this" as implicit parameter in Scala?

Suppose I want to wrap code that can throw exceptions with a try-catch block that logs the exception and continues. Something like:
loggingExceptions {
// something dangerous
}
Ideally, I would like to use for logging the Logger defined on the calling object, if any (and if none, get a compile-time error). I'd love to define something like this:
def loggingExceptions[L <: { def logger: Logger }](work: => Unit)(implicit objectWithLogger: L): Unit = {
try {
work
} catch {
case t: Exception => objectWithLogger.logger.error(t.getMessage)
}
}
where objectWithLogger would somehow "magically" expand to "this" in client code. Is this (or a similar thing) possible?
It can in fact be done just as you want. The other answerers surrendered too quickly. No white flags!
package object foo {
type HasLogger = { def logger: Logger }
implicit def mkLog(x: HasLogger) = new {
def loggingExceptions(body: => Unit): Unit =
try body
catch { case ex: Exception => println(ex) }
}
}
package foo {
case class Logger(name: String) { }
// Doesn't compile:
// class A {
// def f = this.loggingExceptions(println("hi"))
// }
// 1124.scala:14: error: value loggingExceptions is not a member of foo.A
// def f = this.loggingExceptions(println("hi"))
// ^
// one error found
// Does compile
class B {
def logger = Logger("B")
def f = this.loggingExceptions(println("hi"))
def g = this.loggingExceptions(throw new Exception)
}
}
object Test {
def main(args: Array[String]): Unit = {
val b = new foo.B
b.f
b.g
}
}
// output
//
// % scala Test
// hi
// java.lang.Exception
Debilski's answer will work, but I'm not sure I see a good reason to use a structural type (i.e. { def logger: Logger }) here. Doing so will incur extra runtime overhead whenever logger is invoked, since the implementation of structural types relies on reflection. The loggingExceptions method is closely tied to logging, so I would just make it part of a Logging trait:
trait Logging {
def logger: Logger
final def loggingExceptions(body: => Unit) =
try body catch { case e: Exception => logger.error(e.getMessage) }
}
trait ConcreteLogging extends Logging {
val logger = // ...
}
object MyObject extends SomeClass with ConcreteLogging {
def main {
// ...
loggingExceptions {
// ...
}
}
}
You could add a trait to all classes which want to use def loggingExceptions and in this trait add a self-type which expects def logger: Logger being available.
trait LoggingExceptions {
this: { def logger: Logger } =>
def loggingExceptions(work: => Unit) {
try { work }
catch { case t: Exception => logger.error(t.getMessage) }
}
}
object MyObjectWithLogging extends OtherClass with LoggingExceptions {
def logger: Logger = // ...
def main {
// ...
loggingExceptions { // ...
}
}
}