Delayed variable initialization - scala

Let's say I have a variable which I cannot initialize immediately, because I do not know its value (so lazy val won't work for me). I also cannot control the moment the object creation because it is handled by a framework (e.g. Activity in an Android app), so I cannot delay creation of whole object. I do NOT want to use var for this, as it brings the risk of incomplete initialization and invalid states.
So far I've been using approach like:
class MyClass extends InterfaceWithDelayedInitialization {
private val delayedValueP = Promise[Type]()
private val delayedValueF = delayedValueP.future
def onCreate(value: Type): Unit = {
delayedValueP.successful(value)
}
def someOtherMethod(): Unit = {
delayedValueF foreach { value =>
// do something with value
}
}
}
but I cannot help but feel that this approach is kind of smelly (not as smelly as using mutability and vars though).
Is there some standard solution for a problems like this one?

Related

How do I mock a Scala Companion Object with EASYMOCK on Scala 3? [duplicate]

This question already has an answer here:
How to mock an Object in Scala
(1 answer)
Closed 7 months ago.
I have the following code...
class CoreDataSource {
def getConnection = {
println("Getting the connection")
CoreDataSource.getConnection
}
}
object CoreDataSource {
def getConnection: Option[Connection] = {
getDataSource.get.getConnection
}
def getDataSource: Option[DataSource] = {
...
config = new HikariConfig // This has side effects and can't run
...
val pool : DataSource = new HikariDataSource(config) // This has side effects and can't run
...
Some(pool)
}
}
I am trying to mock out the creation of the HikariDataSource and HikariConfig. I tried this...
class CoreDataSourceSpec extends AnyFunSpec with EasyMockSugar {
describe("Core Data Source") {
it("Do something") {
val cdsMock = mock[CoreDataSource.type]
...
}
}
}
But I get
Cannot subclass final class ....CoreDataSource$
What is the proper way to Mock out a companion object using EasyMock
You don't.
Companion object should only perform pure computations (at least don't contain state) which don't require mocking. Most of the time it's purpose is to store factories and instances of type classes (implicits/givens) for your type.
If you store a mutable state (e.g. connection to the database) in companion you messed up. If you have a Java background, think this way: would you mock static methods of a class? (If you're drifting towards PowerMockito you should reconsider your life choices).
Your example shows that you want to store the connection somewhere - storing it in companion is basically global, shared, mutable state which is universally a bad idea, no matter the background.
Create factory of CoreDataSource in its companion, then pass around CoreDataSource instance directly. No issue with mocking that in your tests.
class CoreDataSource(dataSource: DataSource) {
def getConnection: Connection =
dataSource.getConnection
}
object CoreDataSource {
def createHikari(config: HikariConfig): CoreDataSource =
new CoreDataSource(new HikariDataSource(config))
}
// in test:
val dataSource = mock[DataSource]
val coreDataSource = new CoreDataSource(dataSource)
// then mock dataSource.getConnection
Doing it another way requires solving the hard problem that you have 0 reasons to have in the first place. If this companion object is not your but someone else and you cannot rewrite it - wrap it in your own code that you can control and mock easily.
EDIT. In case you are using something like Google Cloud... it still doesn't make sense to store everything in companion and mock it.
// functionality
class MyService(
connection: Connection
) {
def someFunctionality(arg: Arg): Result = ...
}
// in test
// given
val connection = mock[Connection] // mocking DB sounds like a bad idea but whatever
val myService = new MyService(connection)
// when
myService.someFunctionality(arg)
// then
// assertions
// adapter for Google Cloud, other cloud solutions should be similar
class MyFunction extends HttpFunction {
private val config = ...
private val coreDataSource = CoreDataSource.hikari(config)
private val connection = coreDataSource.getConnection
private val myService = new MyService(connection)
override def service(request: HttpRequest, response: HttpResponse): Unit = {
// extract data from request, then
val result = myService.someFunctionality(arg)
// then send result in response
}
}
And if you needed to cache these private vals - what you are caching is NOT related to business logic at all, it merely wires things together, like main in Java which is never tested, nor require testing.
So you could implement it like:
class MyFunction extends HttpFunction {
override def service(request: HttpRequest, response: HttpResponse): Unit = {
// extract data from request, then
val result = MyFunction.myService.someFunctionality(arg)
// then send result in response
}
}
object MyFunction {
// dependency injection and initialization
private val config = ...
private val coreDataSource = CoreDataSource.hikari(config)
private val connection = coreDataSource.getConnection
val myService = new MyService(connection)
}
where wrapper MyFunction is NOT tested, but MyService which does all the job is easily testable.
You should definitely read more about the language, beside the fact that the other answer mentioned (which is you should only contain pure class-level functionalities in the companion object), you cannot do it. Why? Because companion objects are singleton objects of a final class, which can access private states of the companion class itself and vice versa (think of it kind of like static data of the class).
The thing is, companion object actually is an object of a final class (which if you want, I can provide more details about them). Final classes cannot be mocked, simply because they are "final", and their behavior cannot be changed (even by its subclasses). And mocking is all about mocking a class behavior, not an object's behavior.

Setting an immutable field for later use

I'm in a situation where I need to set a certain field in a singleton object so it can be used later.
def register(importantField: String): Unit = {
Factory.setField(importantField)
}
where Factory is:
object Factory {
var field: Option[String] = None
def setField(importantField: String): Unit = {
field = Option(importantField)
}
def functionThatWillBeCalledLater: Unit = {
// do something with member "field"
}
}
but I really want to avoid using var. Is there some kind of idiomatic way to do this?
Don't do this. Global factories, besides being racy and breaking referential transparency, are also a nightmare for unit testing. You should really think about designing your code in a way, where you can keep all the "important fields" where you need them.
The trick is that instead of something like
class Foo {
def doFoo() = Factory.bar
}
Factory.register(param)
new Foo().doFoo()
You would have to write
class Foo {
def doFoo(factory: Factory) = factory.bar
}
new Foo().doFoo(new Factory(param)
Or maybe
class Foo(factory: Factory) {
def doFoo() = factory.bar
}
new Foo(new Factory(param)).doFoo
It may seem a bit tedious compared, to just throwing all the stuff into a global state object, and accessing it from everywhere ... but that's only as long as all of the uses of that function everywhere always use the same value of the parameter (in which case, it is better off just being a constant in the first place) or (perhaps, more importantly) until you start thinking about writing unit tests to test places that use your Factory. You cannot mock an object ... so, what will you do?
Singleton objects have to be thread safe - since the object is static, there's no guarantee that only one thread will access it, so your call not to use a var is totally reasonable. All vals are final and guaranteed to be thread safe, but we can't say the same about vars (and, well, if we're talking about idiomatic, mutable state is generally frowned upon).
You could implement your own getter and setter (using proper synchronization) for a private var, or use a scala.concurrent.Promise for this purpose - a Promise can only be completed once, and is guaranteed to be thread safe.
import scala.concurrent.Promise
object Factory {
private val _field: Promise[String] = Promise()
// the notation below allows you to set it via `Factory.field = "a"`
def field_=(value: String): Boolean = _field.trySuccess(value)
def field: Option[String] = _field.future.value.flatMap(_.toOption)
}
That said, the most idiomatic Scala way to approach factories with variable baseline conditions would be to create one with all the variables set to the values you need. An object is essentially just a val, so instead of an actual singleton object you could instantiate the Factory with all the parameters you need once they're available - and then just use that everywhere.

scala functional way to store state

I want to store a state (key -> value) in scala using functional way. I probably learned while ago in Odersky class but can not remember any more.
Here's my non-functional approach;
import org.scalatest.{FunSuite, Matchers}
trait EventHandler
class StatefulNonFn {
type EventName = String
private var state = Map.empty[EventName, EventHandler]
def update(name: String): EventHandler = {
state.get(name).fold {
val handler = new EventHandler {}
state += name -> handler
handler
}(eh => eh)
}
}
class NonFunctionalStateSpec extends FunSuite with Matchers {
test("stateful") {
val stateResult = new StatefulNonFn().update("MusicAdded")
stateResult.isInstanceOf[EventHandler] shouldBe true
}
}
One attempt I made is to make the state a "function of EventName and previousState" which makes sense but now I can't figure out how do I store those all states?
My first call is going to be fine because the state is empty in that case.
import org.scalatest.{FunSuite, Matchers}
trait EventHandler
class Stateful {
type EventName = String
private val stateFn = new ((String, Map[EventName, EventHandler]) => Map[EventName, EventHandler]) {
override def apply(name: String, prevState: Map[EventName, EventHandler]): Map[EventName, EventHandler] = {
val handler = new EventHandler {}
prevState + (name -> handler)
}
}
def initState = Map.empty[EventName, EventHandler]
def update(name: String, prevState: Map[EventName, EventHandler]) = stateFn(name, prevState)
}
class FunctionalStateSpec extends FunSuite with Matchers {
test("stateful") {
val stateHelper = new Stateful()
val stateResult = stateHelper.update("MusicAdded", stateHelper.initState)
stateResult.keys.size shouldBe 1
val stateResult1 = stateHelper.update("MusicDeleted", stateResult)
stateResult1.keys.size shouldBe 2
//what i obviously want is something like this without me wanting to store the previousStates
//stateHelper.update("MusicAdded1")
//stateHelper.update("MusicAdded2")
}
}
I am not sure, maybe something eventually has to be mutable. How do I Store the previous states in above case? without the client being the one to supply it in each call. Because state can be updated from 5 separate clients without knowing the previous state.
It just turns out that if you want to do some useful program, you need mutations and you need state. You need to do IO, like saving into the database (which could return some different ID every time you do it), or getting a random number, or the current timestamp, or printing into console, etc.
If you are doing functional programming, is not about doing pure, deterministic, total stuff. It's about isolating sideffects (like mutations and state) away.
So strictly pure languages like Haskell do it by returning actions (or plans, or descriptions of actions...) instead of performing them. The runtime performs those actions, so that way you have two things:
Your pure and sexy program
The runtime, in charge of doing the dirty stuff.
However Scala doesn't just expects you to return actions so that the runtime executes them... You need to do it yourself.
That being said, your solution is perfectly ok, if you don't want to go to dark places. Otherwise, I'd recommend you to read this, an article from John Degoes that basically explains how to do what you want (by simultaneously defining what a freemonad is).

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 declare anonymous mixin using a type parameter in Scala

There have been some questions asked that are somewhat related to this problem, but they don't seem to fit quite right.
I'm using the Cake pattern to slide a "Storage" system in place in production code, and a stub storage system in for testing purposes. This is all great, but there's a class that's being instantiated within the original class that also needs to have this stub storage system mixed in. Since it's hidden inside the implementation, I don't have access to it.
Things look like this:
class Main { this: Storage =>
...
val used = Used(...)
...
}
class Used { this: Storage =>
...
}
When testing "Used" I simply new Used with StubStorage and off I go. I used to do the same with Main but that was before it made use of Used. Now that Main makes a naive instantiation of Used I've got this problem.
I wanted to try it this way:
class Main[T <: Storage] { this: T =>
...
val used = Used[T](...)
...
}
class Used[T <: Storage] { this: T =>
...
}
object Used {
def apply[T <: Storage](...) = new Used(...) with T
}
But of course that doesn't work because the compiler doesn't have enough information to discover T. Is there a magic recipe for this? I've played around with it for a bit and it seems to be cumbersome enough that the standard OO injection method is actually less trouble, but I could be missing something.
I've looked at the implicit Factory concept but I can't pound that into shape to work for mixins.
EDIT: It's amazing the clarity that writing the question publicly gives. :) I haven't solved the problem the way I originally intended, but there is a simple solution to the actual problem:
trait UsedProvider {
def createUsed = Used.apply _
}
class Main { this: Storage with UsedProvider =>
val used = createUsed(...)
}
Then I would just do the following in the test: new Main with StubStorage with StubUsedProvider.
I haven't solved your original problem either but have you considered using an abstract class for Main and provide the value for used where you need it?
abstract class Main { this: Storage =>
val s = "s"
val used: Used
}
Then instantiate like this:
val main = new Main with StubStorage { val used = new Used(s) with StubStorage }