Understanding inner classes in trait - scala

I'm pretty new to Scala and now I'm trying to learn how to write tests in Scalatest. Here is an example they provided with the using custom matchers section:
import org.scalatest._
import matchers._
trait CustomMatchers {
class FileEndsWithExtensionMatcher(expectedExtension: String) extends Matcher[java.io.File] {
def apply(left: java.io.File) = {
val name = left.getName
MatchResult(
name.endsWith(expectedExtension),
s"""File $name did not end with extension "$expectedExtension"""",
s"""File $name ended with extension "$expectedExtension"""""
)
}
}
def endWithExtension(expecedExtension: String) = new FileEndsWithExtensionMatcher(expectedExtension)
}
// Make them easy to import with:
// import CustomMatchers._
object CustomMatchers extends CustomMatchers
I do not quite understand the reason they pu the FileEndsWithExtensionMatcher class into a trait? Why? Is it idiomatic scala way or some? Can't you explain it?

It is just for your convienience.
That is one of many ways to modularize your code and than reuse it in desired suites. You can organize it in packages or objects and it will work either. With this approach it is just easy to mix traits into your tests. What's more it allows you to nicely organize connected matchers.
For example you can create trait with group of matchers for currencies and another trait matching physical units. Next you can mixin one or both traits into your Test.

The purpose here is to "put all the matchers into one place from which you can easily access them in other code". You could put all these traits into a package and import that package. But the link you reference states that "One good way to organize custom matchers is to place them inside one or more traits that you can then mix into the suites that need them". It would work either way. It's just a matter of preference.

Related

What are the advantages or disadvantages of declaring function/method in companion objects versus declaring them in traits?

I am new to Scala and I now started a project in Scala and I see similar to the following construct:
trait SomeTrait extends SomeOtherStuff with SomeOtherStuff2
object SomeTrait {
def someFunction():Unit = { ??? }
}
I understand that for a class, companion objects hold methods that are used in a "static", like Factory methods in Java or something alike, but what about traits, why not put these methods in traits?
The first style is called mixin, it used to be somewhat popular back in the days.
It could be replaced by the following code:
object SomeOtherStuff {
def someMethod(): String
}
object SomeObj {
import SomeOtherStuff._
//now someMethod is available
def otherMethod(): String = someMethod + "!"
}
object Caller {
import SomeObj._
import SomeOtherStuff._
//utility methods from both objects are available here
}
Pros of mixins:
If SomeTrait extends 10 other mixins then extending this trait would allow to scrap 10 import statements
Cons of mixins:
1) creates unnecessary coupling between traits
2) awkward to use if the caller doesn't extend the mixin itself
Avoiding mixins for business-logic code is a safe choice.
Although I'm aware of 2 legitimate usecases:
1) importing DSLs
e.g. ScalaTest code :
class SomeSuite extends FunSuite with BeforeAndAfter {...}
2) working (as a library author) with implicit parameters:
e.g. object Clock extends LowPriorityImplicits
(https://github.com/typelevel/cats-effect/blob/master/core/shared/src/main/scala/cats/effect/Clock.scala#L127)
Another perspective to this is the OOP principle Composition Over Inheritance.
Pros of companion objects (composition):
composition can be done at runtime while traits are defined at compile time
you can easily have multiple of them. You don't have to deal with the quirks of multiple inheritance: say you have two traits that both have a method with the name foo - which one is going to be used or does it work at all? For me, it's easier to see the delegation of a method call, multiple inheritance tends to become complex very fast because you lose track where a method was actually defined
Pros of traits (mixins):
mixins seem more idiomatic to reuse, a class using a companion object of another class is odd. You can create standalone objects though.
it's cool for frameworks because it adds the frameworks functionality to your class without much effort. Something like that just isn't possible with companion objects.
In doubt, I prefer companion objects, but it always depends on your environment.

ScalaTest: Is there a flaw defining Test Suites as object rather than class?

I have a very specific use-case and in order to reduce instantiation time for the test suites I define them as an object and not as a class e.g.
import org.scalatest._
import scala.collection.mutable.Stack
object StackSuite extends FunSuite with Matchers {
test("stackShouldPopValuesIinLastInFirstOutOrder") {
val stack = new Stack[Int]
stack.push(1)
stack.push(2)
stack.pop() should equal(2)
stack.pop() should equal(1)
}
}
This works but is there a fundamental issue or flaw regarding doing this? separate from the multithreading issue should each test be executed separately and in the unfortunate case of having modifyable state at the suite level.
UPDATE: when I say "reduce instantiation time" I meant overall e.g. accounting for heavyweight fixture data inside the object/class and not simply the pure Suite class instantiation time. Since object is a singleton then it would be a lookup rather than an instantiation of a new class.
I need to do this in order to distribute millions of tests across a grid of computers. Some tests are standard scalatest others are evaluating the permutations of a set of input parameters therefore the need to reduce the startup time for the instantiation of the Suite.
btw I do this to execute each test in a cluster machine:
import scala.reflect.runtime.universe
// I receive the suite and test names as input
val suite = "com.mycomp.StackSuite"
val test = "stackShouldPopValuesIinLastInFirstOutOrder"
val runtimeMirror = universe.runtimeMirror(getClass.getClassLoader)
val module = runtimeMirror.staticModule(suite)
val obj = runtimeMirror.reflectModule(module)
val status = obj.asInstanceOf[TestSuite].execute(test)
in order to reduce instantiation time for the test suites I define them as an object and not as a class
I had a quick look at org.scalatest.tools.Runner (and DiscoverySuite) implementation, and I don't think this can reduce the instantiation time.
Remember how objects are actually compiled on JVM: you have a class StackSuite$ which extends Suite and has a public parameterless constructor (because it has to be called from StackSuite's static initializer). It's found and handled precisely like a class StackSuite would be.
EDIT: if you find the suite and run it yourself in this way instead of using ScalaTest's own API, then yes, you'll get a lookup instead of instantiation. Assuming no concurrency issues, there should be no problem: execute itself is threadsafe.
If you do not feel the need to modularize your testing by using inheritance then there is no problem in using an Object instead of a class. Else classes can help you in segregating the different kinds of testing.
From the ScalaTest docs :
Instead of duplicating code by mixing the same traits together repeatedly, we recommend you create abstract base classes for your project that mix together the features you use the most. For example, you might create a UnitSpec class (not trait, for speedier compiles) for unit tests that looks like:
package com.mycompany.myproject
import org.scalatest._
abstract class UnitSpec extends FlatSpec with Matchers with
OptionValues with Inside with Inspectors
You can then write unit tests for your project using the custom base class, like this:
package com.mycompany.myproject
import org.scalatest._
class MySpec extends UnitSpec {
// Your tests here
}

Instantiating all classes that extend trait in Scala

So I'm building a library, and the problem I have is as follows:
I have a trait, such as
package my.library
trait Animal {
def randomFunctions
}
What I need to know is all the classes the consumer code has, that extend/implement said trait, such as
package code.consumer
case class Cat extends Animal
case class Dog extends Animal
So in summary: inside my library (which has the trait) I need to find out all classes (in consumer code) that extend/implement the trait.
I finally solved this by using reflections (https://github.com/ronmamo/reflections) with the following little snippet:
val reflection = new Reflections()
reflection.getSubTypesOf(classOf[Animal])
An option would be to use a sealed trait. This forces all implementations of the trait to reside in the same file as the trait was defined.
This would break your separation of consumer and library code but you would be sure to get all implementations.
The only other option I can think of is to use an IDE, like IntelliJ which has an option to find all implementation based on given trait.

How to (properly) enrich the standard library?

I would like to define an implicit conversion from Iterator[T] to a class that I have defined: ProactiveIterator[A].
The question isn't really how to do it but how to do it properly, i.e. where to place the method, so that it is as transparent and unobtrusive as possible. Ideally it should be as the implicit conversion from String to StringOps in scala.Predef If the conversion was from a class in the library to some other class, then it could be defined inside that class, but AFAIK that's not possible here.
So far I have considered to add an object containing these conversions, similarly to JavaConversions, but better options may be possible.
You don't really have much of a choice. All implicits must be contained within some sort of object, and imported with a wildcard import (you could import them individually, but I doubt you want that).
So you'll have some sort of implicits object:
package foo.bar
object Implicits {
implicit class ProactiveIterator[A](i: Iterator[A]) {
...
}
}
Then you must explicitly import it wherever you use it:
import foo.bar.Implicits._
In my opinion, this is a good thing. Someone reading the code might not understand where your pimped methods are coming from, so the explicit import is very helpful.
You can similarly place your implicits within a package object. You would have to import them the same way into other namespaces, but they would be available to classes within the same package.
For example, using the following, anything within foo.bar will have this implicit class available:
package foo
package object bar {
implicit class ProactiveIterator[A](i: Iterator[A]) {
...
}
}
Elsewhere you would import foo.bar._ (which may or may not be as clean, depending on what's in bar).

"dynamically" creating case classes with macros

I would like to create a macro generated hierarchy of sealed abstract and case classes. There was an example similar to this with http://docs.scala-lang.org/overviews/macros/typemacros.html but is is now obsolete. Is this still possible?
I think it would be incredibly powerful to generate a type safe AST for some specified grammar. Ideally with an IDE able to resolve all the classes.
First for some shameless self-promotion: Eugene Burmako and I are giving a talk on type providers, a closely related topic, at Scalar 2014 tomorrow, and I encourage you to take a look at the example project we put together for the talk if you're interested in this kind of thing.
While type macros are no longer supported, you can accomplish essentially the same thing with macro annotations from macro paradise (which is available as a plugin for Scala 2.10 and 2.11):
import scala.annotation.StaticAnnotation
import scala.language.experimental.macros
import scala.reflect.macros.Context
// Add constructor arguments here.
class expand extends StaticAnnotation {
def macroTransform(annottees: Any*) = macro Expander.expand_impl
}
object Expander {
def expand_impl(c: Context)(annottees: c.Expr[Any]*) = {
import c.universe._
annottees.map(_.tree) match {
case List(q"trait $name") => c.Expr[Any](
// Add your own logic here, possibly using arguments on the annotation.
q"""
sealed trait $name
case class Foo(i: Int) extends $name
case class Bar(s: String) extends $name
case object Baz extends $name
"""
)
// Add validation and error handling here.
}
}
}
And then:
scala> #expand trait MyADT
defined trait MyADT
defined class Foo
defined class Bar
defined module Baz
You can add arguments to the annotation that will be available at compile time, allowing you to parse an external resource that you can use to generate the implementation of the ADT, for example.
Macro annotations are very experimental and their status is still up in the air—there's no guarantee that they'll ship with Scala 2.12, for example. Something similar (although not quite so clean) is possible using plain old def macros and structural types—see the example project linked above for more detail and some demonstrations. In any case, this kind of mechanism is of interest to many people, including the developers of Scala's macro system, so even if macro annotations disappear at some point down the road, there's likely to be some way to accomplish what you've described here.