Scala object constructor - scala

I have to create a file loader object and I would like the file to be loaded only once at object creation.
What I did until now is create a trait with a method read that will read file and output a list of String.
trait Loader {
protected val readSource: List[String] = {
Source
.fromInputStream(getClass.getResourceAsStream("filename"), "UTF-8")
.getLines()
.toList
}
def transform(delimeter: String): Vector[C] = {
val lines = readSource
// process the lines
}
}
The trait is implemented by several object, and the transform method can be called multiple times in the client code.
I would like to avoid re reading the file each time the transform method is called and my first solution was to extract the val lines = readSource from the transform method and make a function of it def loadFile = readSource and to create a apply method in my objects to call loadFile like so :
object MyLoader extends Loader {
def apply: List[String] = {
loadFile
}
}
I am wondering if this is the right way to do it. Thank you for your advices.

If you want the resource read once for all, then you should do that in a singleton object, which will be initialized once lazily.
Clients should use that object. "Prefer composition over inheritance" is the mantra.
If you want a mix-in that makes it easy to use the object, you can use "self-types" to constrain clients:
trait HasResource { val resource: R = TheResource }
trait Client { self: HasResource => def getR: R = resource }
This is the "cake pattern" way of making stuff available.

Related

How to test a method by mocking nested methods?

I'm trying to test an Object.method which contains some nested methods from a Trait apart of some calculations. These nested methods have to be mocked (they access to a DB so I want to mock their responses).
When I call the real Object.method, it should skip the nested methods call and retrieve what I want. I've tried mocking them but test is still calling them.
Here's my example source code:
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyObject extends MyTrait {
def myParentMethod(a:String) = {
val b = myMethodToMock(a)
val c = a + b
c
}
}
Then in my test:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(a)).thenReturn(b)
//Then I call the parent method:
assert(MyObject.myParentMethod(a) equals c)
It throws a NullPointerException as it's still accessing to myMethodToMock
Your code does not compile, so I am going to guess some things of what you are actually trying to do here ...
You are stubbing a method on a mock, and then calling it on a completely unrelated instance. No wonder it does not work.
A good rule of thumb (and the best practice) is to never mock classes you are actually testing. Split everything you want to mock and test separately into a separate class. This is also known as single responsibility principle (each component should be responsible for a single thing).
trait MyTrait {
def myMethodToMock(a: String): String
}
object MyTrait extends MyTrait {
def myMethodtoMock(a: String) = ???
}
class MyObject(helper: MyTrait = MyTrait) {
def myParentMethod(a: String) = a + helper.myMethodToMock(a)
}
object MyObject extends MyObject()
Now, you can write your test like this:
val myTraitMock = mock[MyTrait]
when(myTraitMock.myMethodToMock(any)).thenReturn("b")
new MyObject(myTraitMock).myParentMethod("a") shouldBe "ab"
verify(myTraitMock).myMethodToMock("a")
The main difference here is that you are passing your mock into the object's constructor, so that when it calls the method, it will be the one you stubbed, not the implementation provided by the default class.
You should use composition rather than inheritance, so you can inject an instance of MyTrait that can be a mock or the real one

How to swap JSON Writes Converter for Play controller Action

I've built a microservice using Scala and Play and now I need to create a new version of the service that returns the same data as the previous version of the service but in a different JSON format. The service currently uses implicit Writes converters to do this. My controller looks something like this, where MyJsonWrites contains the implicit definitions.
class MyController extends Controller with MyJsonWrites {
def myAction(query: String) = Action.async {
getData(query).map {
results =>
Ok(Json.toJson(results))
}
}
}
trait MyJsonWrites {
implicit val writes1: Writes[SomeDataType]
implicit val writes2: Writes[SomeOtherDataType]
...
}
Now I need a new version of myAction where the JSON is formatted differently. The first attempt I made was to make MyController a base class and have subclasses extend it with their own trait that has the implicit values. Something like this.
class MyNewContoller extends MyController with MyNewJsonWrites
This doesn't work though because the implicit values defined on MyNewJsonWrites are not available in the methods of the super class.
It would be ideal if I could just create a new action on the controller that somehow used the converters defined in MyNewJsonWrites. Sure, I could change the trait to an object and import the implicit values in each method but then I'd have to duplicate the method body of myAction so that the implicits are in scope when I call Json.toJson. I don't want to pass them as implicit parameters to a base method because there are too many of them. I guess I could pass a method as a parameter to the base method that actually does the imports and Json.toJson call. Something like this. I just thought maybe there'd be a better way.
def myBaseAction(query: String, toJson: Seq[MyResultType] => JsValue) = Action.async {
getData(query).map {
results =>
Ok(Json.toJson(results))
}
}
def myActionV1(query: String) = {
def toJson(results: Seq[MyResultType]) = {
import MyJsonWritesV2._
Json.toJson(results)
}
myBaseAction(query, toJson)
}
Instead of relying on scala implicit resolution, you can call your writes directly:
def myBaseAction(query: String, writes: Writes[MyResultType]) = Action.async {
getData(query).map { results =>
val seqWrites: Writes[Seq[MyResultType]] = Writes.seq(writes)
Ok(seqWrites.writes(results))
}
}
def myActionV1(query: String) = myBaseAction(query, MyJsonWritesV1)
def myActionV2(query: String) = myBaseAction(query, MyJsonWritesV2)

How could I reimplement Tie::File in Scala?

I really like Tie::File, which allows you to tie an array to a file's lines. You can modify the array in any way, and when you're done with it, you untie it, and the file's content modifies accordingly.
I'd like to reimplement such behaviour in Scala, and this is what I have so far:
class TiedBuffer(val file:File) extends ArrayBuffer[String] {
tieFile
def untie = {
val writer = new PrintStream(new FileOutputStream(file))
this.foreach(e => writer.println(e))
writer.close
this
}
private def tieFile = this ++= scala.io.Source.fromFile(file).getLines()
}
However, the "operators" defined on the ArrayBuffer return various classes, different than my own, for example:
println((new TiedBuffer(somefile) +: "line0").getClass)
gives me a immutable.Vector. I could limit the class to a very small set of predefined methods, but I thought it would be nice if I could offer all of them ( foreach/map/... ).
What should I inherit from, or how should I approach this problem so that I have a fluid array-like interface, which allows me to modify a file's contents?
BOUNTY: to win the bounty, can you show a working example that makes use of CanBuildFrom to accomplish this task?
The methods ending with colon are right associative so in your example you are calling +: of String with a TiedBuffer as parameter. If you want to test +: from ArrayBuffer you can do:
println((new TiedBuffer(somefile).+:("line0")).getClass)
or
println(("line0" +: new TiedBuffer(somefile)).getClass)
EDIT
I missed the point in your question, see John's answer to return TiedBuffer objects instead of ArrayBuffer.
EDIT2
Here is an example with CanBuildFrom. You will have to call tie manually though to prevent the file to be tied every time the builder create a new TiedBuffer instance. There is still a lot of room for improvement, for instance ++ will not work but it should get you started.
import collection.generic.CanBuildFrom
import collection.mutable._
import java.io.{PrintStream, FileOutputStream, File}
class TiedBuffer(val file: File) extends ArrayBuffer[String]
with BufferLike[String, TiedBuffer]
with IndexedSeqOptimized[String, TiedBuffer] {
def tie = {
clear
this ++= scala.io.Source.fromFile(file).getLines()
}
def untie = {
val writer = new PrintStream(new FileOutputStream(file))
this.foreach(e => writer.println(e))
writer.close
this
}
override def newBuilder: Builder[String, TiedBuffer] =
new ArrayBuffer mapResult {
x: Seq[String] => (new TiedBuffer(file) ++= x)
}
}
object TiedBuffer {
implicit def canBuildFrom: CanBuildFrom[TiedBuffer, String, TiedBuffer] =
new CanBuildFrom[TiedBuffer, String, TiedBuffer] {
def apply(): Builder[String, TiedBuffer] =
throw new RuntimeException("Cannot create a new TiedBuffer from scratch")
def apply(from: TiedBuffer): Builder[String, TiedBuffer] = from.newBuilder
}
}
Extending existing collection requires defining a builder in a companion object such as
object TiedBuffer {
implict def canBuildFrom[T] = new CanBuildFrom[TiedBuffer[T],T,TiedBuffer[T]] { ... }
}
This is fully explained here:
http://www.scala-lang.org/docu/files/collections-api/collections-impl.html
As noted by Marx Jayxcela, the reason you are getting a Vector is that you are using a right associative operators, otherwise an implicit builder would be selected and you would get an ArrayBuffer

Force initialization of Scala singleton object

I'm working on an automatic mapping framework built on top of Dozer. I won't go into specifics as it's not relevant to the question but in general it's supposed to allow easy transformation from class A to class B. I'd like to register the projections from a class's companion object.
Below is a (simplified) example of how I want this to work, and a Specs test that assures that the projection is being registered properly.
Unfortunately, this doesn't work. From what I can gather, this is because nothing initializes the A companion object. And indeed, if I call any method on the A object (like the commented-out hashCode call, the projection is being registered correctly.
My question is - how can I cause the A object to be initialized automatically, as soon as the JVM starts? I don't mind extending a Trait or something, if necessary.
Thanks.
class A {
var data: String = _
}
class B {
var data: String = _
}
object A {
projekt[A].to[B]
}
"dozer projektor" should {
"transform a simple bean" in {
// A.hashCode
val a = new A
a.data = "text"
val b = a.-->[B]
b.data must_== a.data
}
}
Short answer: You can't. Scala objects are lazy, and are not initialized until first reference. You could reference the object, but then you need a way of ensuring the executing code gets executed, reducing the problem back to the original problem.
In ended up doing this:
trait ProjektionAware with DelayedInit
{
private val initCode = new ListBuffer[() => Unit]
override def delayedInit(body: => Unit)
{
initCode += (() => body)
}
def registerProjektions()
{
for (proc <- initCode) proc()
}
}
object A extends ProjektionAware {
projekt[A].to[B]
}
Now I can use a classpath scanning library to initialize all instances of ProjektionAware on application bootstrap. Not ideal, but works for me.
You can force the instantiation of A to involve the companion object by using an apply() method or some other sort of factory method defined in the object instead of directly using the new A() constructor.
This does not cause the object to be initialized when the JVM starts, which I think as noted in another answer can't generally be done.
As Dave Griffith and Don Roby already noted, it cannot be done at JVM startup in general. However maybe this initialization could wait until first use of your framework?
If so, and if you don't mind resorting to fragile reflection tricks, in your --> method you could obtain reference to the companion object and get it initialize itself.
You can start at Getting object instance by string name in scala.
We could use this sort of a way to ensure that companion object gets initialized first and then the class gets instantiated.
object B {
val i = 0
def apply(): B = new B()
}
class B {
// some method that uses i from Object B
def show = println(B.i)
}
// b first references Object B which calls apply()
// then class B is instantiated
val b = B()

How to log in Scala *without* a reference to the logger in *every instance*?

I've looked at example of logging in Scala, and it usually looks like this:
import org.slf4j.LoggerFactory
trait Loggable {
private lazy val logger = LoggerFactory.getLogger(getClass)
protected def debug(msg: => AnyRef, t: => Throwable = null): Unit =
{...}
}
This seems independent of the concrete logging framework. While this does the job, it also introduces an extraneous lazy val in every instance that wants to do logging, which might well be every instance of the whole application. This seems much too heavy to me, in particular if you have many "small instances" of some specific type.
Is there a way of putting the logger in the object of the concrete class instead, just by using inheritance? If I have to explicitly declare the logger in the object of the class, and explicitly refer to it from the class/trait, then I have written almost as much code as if I had done no reuse at all.
Expressed in a non-logging specific context, the problem would be:
How do I declare in a trait that the implementing class must have a singleton object of type X, and that this singleton object must be accessible through method def x: X ?
I can't simply define an abstract method, because there could only be a single implementation in the class. I want that logging in a super-class gets me the super-class singleton, and logging in the sub-class gets me the sub-class singleton. Or put more simply, I want logging in Scala to work like traditional logging in Java, using static loggers specific to the class doing the logging. My current knowledge of Scala tells me that this is simply not possible without doing it exactly the same way you do in Java, without much if any benefits from using the "better" Scala.
Premature Optimization is the root of all evil
Let's be clear first about one thing: if your trait looks something like this:
trait Logger { lazy val log = Logger.getLogger }
Then what you have not done is as follows:
You have NOT created a logger instance per instance of your type
You have neither given yourself a memory nor a performance problem (unless you have)
What you have done is as follows:
You have an extra reference in each instance of your type
When you access the logger for the first time, you are probably doing some map lookup
Note that, even if you did create a separate logger for each instance of your type (which I frequently do, even if my program contains hundreds of thousands of these, so that I have very fine-grained control over my logging), you almost certainly still will neither have a performance nor a memory problem!
One "solution" is (of course), to make the companion object implement the logger interface:
object MyType extends Logger
class MyType {
import MyType._
log.info("Yay")
}
How do I declare in a trait that the
implementing class must have a
singleton object of type X, and that
this singleton object must be
accessible through method def x: X ?
Declare a trait that must be implemented by your companion objects.
trait Meta[Base] {
val logger = LoggerFactory.getLogger(getClass)
}
Create a base trait for your classes, sub-classes have to overwrite the meta method.
trait Base {
def meta: Meta[Base]
def logger = meta.logger
}
A class Whatever with a companion object:
object Whatever extends Meta[Base]
class Whatever extends Base {
def meta = Whatever
def doSomething = {
logger.log("oops")
}
}
In this way you only need to have a reference to the meta object.
We can use the Whatever class like this.
object Sample {
def main(args: Array[String]) {
val whatever = new Whatever
whatever.doSomething
}
}
I'm not sure I understand your question completely. So I apologize up front if this is not the answer you are looking for.
Define an object were you put your logger into, then create a companion trait.
object Loggable {
private val logger = "I'm a logger"
}
trait Loggable {
import Loggable._
def debug(msg: String) {
println(logger + ": " + msg)
}
}
So now you can use it like this:
scala> abstract class Abstraction
scala> class Implementation extends Abstraction with Loggable
scala> val test = new Implementation
scala> test.debug("error message")
I'm a logger: error message
Does this answer your question?
I think you cannot automatically get the corresponding singleton object of a class or require that such a singleton exists.
One reason is that you cannot know the type of the singleton before it is defined. Not sure, if this helps or if it is the best solution to your problem, but if you want to require some meta object to be defined with a specific trait, you could define something like:
trait HasSingleton[Traits] {
def meta: Traits
}
trait Log {
def classname: String
def log { println(classname) }
}
trait Debug {
def debug { print("Debug") }
}
class A extends HasSingleton[Log] {
def meta = A // Needs to be defined with a Singleton (or any object which inherits from Log}
def f {
meta.log
}
}
object A extends Log {
def classname = "A"
}
class B extends HasSingleton[Log with Debug] { // we want to use Log and Debug here
def meta = B
def g {
meta.log
meta.debug
}
}
object B extends Log with Debug {
def classname = "B"
}
(new A).f
// A
(new B).g
// B
// Debug