Scala Object inside Trait - scala

In Scala Objects are singletons... so if I make:
trait SimpleTrait {
def setString(s: String): Unit = {
InnerTraitObject setString s
}
def getString(): String = {
return InnerTraitObject getString
}
object InnerTraitObject {
var str: String = ""
def setString(s: String): Unit = {
str = s
}
def getString(): String = {
return str
}
}
}
Then
class SimpleClass extends SimpleTrait{
/// empty impl
}
and:
object App {
def main(args: Array[String]): Unit = {
val a = new SimpleClass();
val b = new SimpleClass();
a.setString("a");
println("A value is " + a.getString());
println("B value is " + b.getString());
}
}
I would like to see
A value is a
B value is a
but i got
A value is a
B value is
My question is:
If object is singleton then why if i put it into Trait then it behave like common object?

It´s not a global singleton, it´s a singleton referring to the instance of the trait (which can have several instances). It depends where you define the singleton: if defined in a package then it´s singleton concerning the package and the package is singleton, too, so the object is singleton. You see, it depends on the context you are defining something as a singleton. If the context is singleton then the defined object too.

Related

How to select an object at runtime - Scala

I need to select an object implementation based on the generics passed. Here is a small example of what I want
import scala.reflect.runtime.universe.{TypeTag,typeOf}
trait Animal27
{
val name: String
val sound: String
}
case class Tiger27(name:String, sound: String) extends Animal27
object Tiger27
{
def AbilityEvolve(tiger27 : Tiger27) : String =
{
tiger27.name + " is a tigher and she has increased attack"
}
}
case class Cheetah27(name:String,sound:String) extends Animal27
object Cheetah27
{
def AbilityEvolve(cheetah27: Cheetah27): String =
{
cheetah27.name + "is a cheethah and he has increased speed"
}
}
class World[A: TypeTag] {
def getMyObject =
{
if (typeOf[A] =:= typeOf[Cheetah27])
Cheetah27
else
Tiger27
}
def Evolve : String =
{
getMyObject.AbilityEvolve + " hence evolved" // how do i perform
//getMyObject.AbilityEvolve
}
}
object App27 extends App{
val world = new World[Cheetah27]
println(world.Evolve)
}
May I know how to dynamically select the object based on the generic used. That is how to make sure that getMyObject.AbilityEvolve is able to call the respective object's method?
Thanks
The ideal solution would be to make all of the possible return types inherit from some common trait. So if you needed to select between FirstObject and SecondObject which both have a foo method, define a HasFoo trait and have both objects mix in that trait.
trait HasFoo {
def foo(): Unit
}
object FirstObject extends HasFoo {
def foo() = { println("FirstObject") }
}
object SecondObject extends HasFoo {
def foo() = { println("SecondObject") }
}
object WithTraits {
def decideAtRuntime(x: Boolean): HasFoo =
if (x) FirstObject else SecondObject
}
The benefit to this is that it's efficient. The JVM runtime was built to do polymorphism like this, and it's clear to the reader as well. If you don't have control over the objects which are being returned, you can always use implicits to add support for the new trait.
However, perhaps your return type is too generic, or there is some other extenuating circumstance. In that case, there is another way. Scala supports what's known as structural typing. That is, you can define a type (not a class; there is a difference) which contains exactly all of the objects that have a foo method.
object FirstObject {
def foo() = { println("FirstObject") }
}
object SecondObject {
def foo() = { println("SecondObject") }
}
object WithStructure {
def decideAtRuntime(x: Boolean): { def foo(): Unit } =
if (x) FirstObject else SecondObject
}
Note the return type of decideAtRuntime. It's not a class name but { def foo(): Unit }. This is a structural type for any object that has a method foo which takes zero arguments and returns nothing.
Structural types are still typesafe, as Scala's compiler will verify that the methods do in fact exist at compile-time. However, it compiles down to JVM instructions that use the Object class and reflection. This means that if a Java API tries to interface with it, the Java API may not be typesafe. It also means that, because of the way the reflection API works, every call to decideAtRuntime will slow your program down.

Scala: Companion object with arguments

I am looking for a way to initialize a companion object with arguments. I tried this, it has the risk for re-instantiation.
private[mypackage] class A(in:Int) {
def method = {}
}
object A {
var singleton: Option[A] = None
def getInstance(): A = {
if(singleton.isDefined)
singleton.get
else {
throw InitializationException("Object not configured")
}
}
def getInstance(in:Int): A = {
singleton = Some(new A(in))
singleton.get
}
}
Is there a better way?
Pure Scala way
Scala allows you to create a singleton object of a type using object keyword. Scala ensures only one instance of A is available in the system.
private[myPackage] object A {
val configValue = Config.getInt("some_value")
def fn: Unit = ()
}
type of A object
scala> object A {}
defined object A
scala> :type A
A.type
more about singleton objects in scala Explanation of singleton objects in Scala
Guice Annotations
import com.google.inject.Singleton
#Singleton
class A (val value: Int) {
def fn: Unit = ()
}
Classic Java way
Use synchronized keyword to protect the getInstance from creating more than one object when called. of course constructor of the class has to be private
You can use a lazy val to delay creation of your singleton, and base it on a var that should be updated once during start-up sequence:
object A {
// will be instantiated once, on first call
lazy val singleton: A = create()
private var input: Option[Int] = None
// call this before first access to 'singleton':
def set(i: Int): Unit = { input = Some(i) }
private def create(): A = {
input.map(i => new A(i))
.getOrElse(throw new IllegalStateException("cannot access A before input is set"))
}
}

Scala: Mocking an enclosed object

I'm trying to write a unit test for object A, which uses some methods from another object B. How do I override B's methods?
A.scala
import somePackage.B
object A { // This is to be tested
def fun1(str: String) = {
val str2 = processStr(str) //Say str2 = "sahil"
B.doSomething(str2) // This is to be overridden
}
B.scala
object B {
private def doSomething(str: String) = {
// do something
"abc"
}
}
ATest.scala
class ATest extends FlatSpec {
it "should return sahil instead of abc" in {
// Do something to override B.doSomething
A.fun1("someString")
}
}
This is a design failure at architectural level and a typical XY problem. You should not use singleton without a (really) compelling reason.
Instead for both testability and modularity, consider injecting your dependency explicitly (right now you are declaring the dependency between A and B implicitly through singleton).
class A(b: B) {
def fun1(str: String) = b.doSomething(str)
}
class B {
def doSomething(str: String) = "abc"
}
class ATest extends FlatSpec {
it "" in {
val b = new B { override def doSomething(str: String) = "testing..." }
val a = new A(b)
a.fun1("someString") must beEqual "testing..."
}
}
There is no easy way to do this. Without using DI the only thing that comes to my mind is to overload fun1 with package-private modifier:
package somePackage
import somePackage.B
object A {
def fun1(str: String) = fun1(B.doSomething)
private[somePackage] def fun1(str: String, f: (String) => String) = {
val str2 = processStr(str)
f(str2)
}
}
Then you can pass any mock you would like into fun1

implicit value not applied in scope

i'm trying to import a implicit Write declaration from an embedded object into a function that produces a JSON object based on a set of case classes.
case class TestModel(test:String)
object TestModel {
def manyToJSON(models: List[TestModel]) = {
import writes.micro
Json.toJson(models)
}
object writes {
implicit val micro = Json.writes[TestModel]
}
}
unfortunately, the scala compiler complains:
No Json serializer found for type List[models.TestModel]. Try to implement an implicit Writes or Format for this type.
the fun part is, if i'm using the write object as a pure expression within the method, its working.
object TestModel {
def manyToJSON(models: List[TestModel]) = {
import writes.micro
writes.micro
Json.toJson(models)
}
object writes {
implicit val micro = Json.writes[TestModel]
}
}
how would i have to change my code to have the implicit in scope?
the reason case class implicit is not working is that it is just a definition not value. Use case object will solve this issue like object. Consider this code:
object MainClass {
def main(args: Array[String]) {
TestModel.manyToJSON(Nil)
}
}
case class TestModel(test:String)
object TestModel {
def manyToJSON(models: List[TestModel]) = {
import writes._
def print(implicit x: Int) = {
println(x)
}
print // print 3
}
object writes {
implicit val x: Int = 3
//implicit val x = 3 //compilation error
}
}

How to get a reference to the actor instance that runs a function?

I have a program structured as follows:
abstract class OuterClass
{
class InnerClass extends Actor
{
loop
{
react
{
case m: T => someFunction(m)
}
}
def someFunction(m: T)
{
...search function map for specific function...
specificFunction()
}
...extra methods here...
}
var functionmap=scala.sollection.mutable.Map.empty[String,()=>String]
var actorpool: ArrayBuffer[Actor]=new ArrayBuffer(0)
def main(args: Array[String])
{
...create X actors and add them to the pool...
populatefunctionmap
}
def populatefunctionmap() //defined elsewhere
}
class RunMe extends OuterClass
{
def populatefunctionmap()
{
...add some functions to the map...
}
}
The problem I have is that I would like to make use of the extra functions available within the actor instance that runs my functionmap functions. When I've tried using this it refers to the extending RunMe class. Using self just results in a not found: value self compiler error.
Is what I want to do possible? If so, how?
A couple of points I'd like to make about your code:
functionmap is both a var and mutable Map. Typically you only need it to be one or the other; not both.
Same goes for actorpool.
Access to shared, mutable state violates the design principles of the actor model.
Given the skeleton you provided, I'm assuming that you don't need to change the functionmap after it's been initialized. Instead of making it a mutable var, make it an immutable val.
You can do that by either an abstract val (shown here), or by a constructor parameter.
abstract class OuterClass {
class InnerClass extends Actor {
def act() {
loop {
react {
case m: T => someFunction(m)
}
}
}
def someFunction(m: T) {
// ...search functionmap for specific function...
for (specificFunction <- functionmap.get(key)) {
specificFunction()
}
}
}
// abstract val
val functionmap: Map[String, () => String]
val actorpool: ArrayBuffer[Actor]=new ArrayBuffer(0)
def main(args: Array[String]) {
// ...create X actors and add them to the pool...
}
}
class RunMe extends OuterClass {
val functionmap = {
// ...build the function map...
}
}
If you need to change functionmap after the actors are created, then InnerClass needs to have a var which holds their own functionmap, which you change by sending messages to the actors.
If I understand correctly, your question has nothing to do with Actors. It boils down to:
abstract class Outer {
class Inner {
def innerf = 42
}
}
class RunMe extends Outer {
val inst = new Inner
def ref = inst.innerf
}
scala> (new RunMe).ref
res0: Int = 42
scala> val r = new RunMe
scala> (new r.Inner).innerf
res1: Int = 42
The inner class's methods are only available on an instance of that inner class, so you need to start by making some instances.
If you'd like to access methods of InnerClass from the functions in functionmap, then it should be of type InnerClass => String, so you have the instance you want to call methods on.