Scala problem optional constructor - scala

Imagine this simple piece of code:
class Constructor() {
var string: String = _
def this(s: String) = {this() ; string = s;}
def testMethod() {
println(string)
}
testMethod
}
object Appl {
def main(args: Array[String]): Unit = {
var constructor = new Constructor("calling elvis")
constructor = new Constructor()
}
}
The result is
null
null
I would like to be
calling elvis
null
How to achieve this? I cannot call the method testMethod after the object creation.
Mazi

Your test method is called in the main constructor first thing. There is no way another constructor might avoid it being called before its own code runs.
In your case, you should simply reverse which constructor does what. Have the main constructor have the string parameter, and the auxiliary one set it to null. Added gain, you can declare the var directly in the parameter list.
class Constructor(var s: String) {
def this() = this(null)
def testMethod() = println(s)
testMethod()
}
In general, the main constructor should be the more flexible one, typically assigning each field from a parameter. Scala syntax makes doing exactly that very easy. You can make that main constructor private if need be.
Edit: still simpler with default parameter
class Constructor(var s: String = null) {
def testMethod = println(s)
testMethod
}

Related

Mock a function within Scala object using Mockito

I have a similar problem as mentioned in link: How to mock a function within Scala object using Mockito?
I have an object FooInner with method stringData, which takes int and give string output
object FooInner {
def stringData(data: Int): String = {
data match {
case 1 => "one"
case _ => "else"
}
}
}
Another object, FooOuter, calls FooInner to get string data and perform some operation on it.
object FooOuter {
def dummyCall(data: Int): String = {
FooInner.stringData(data) + "some operation"
}
}
My aim is to test method FooOuter.dummyCall for string data, NOT returned by FooInner.stringData
For same, I followed above mentioned post and created trait
trait TFooInner {
def stringData(data: Int): String
}
Changed signature of FooInner to
object FooInner extends TFooInner {..}
And created test class FooTests
class FooTests extends FlatSpec with Matchers with MockitoSugar{
"dummyCall" should "mocked data" in {
val service = mock[TFooInner]
when(service.stringData(1)).thenReturn("1") // mocked service data -> 1
assert(FooOuter.dummyCall(1) === "1-some operation") // TestFailedException: "[one]-some operation" did not equal "[1]-some operation"
}
}
, but I am still not able to get mocked service data "1".
I have following questions:
How can I make FooOuter testable with data, not returned from FooInner
Is it right functional style to code in Scala? What I feel is FooOuter is now tightly-coupled/dependent on FooInner
Scala: 2.11
Mockito: 1.9.5
You have to alter both Inner and Outer objects to make them testable.
In general, you should never invoke object methods directly, if you might want to stub them for testing. Such methods should be implemented and accessed via instance calls:
class FooInner {
def stringData(data: Int): String = { ... }
}
object FooInner extends FooInner
class FooOuter(inner: FooInner) {
def dummyCall(data: Int): String = inner.stringData(data) + "bar"
}
object FooOuter extends FooOuter(FooInner)
Now, in your test, you can do
val inner = mock[FooInner]
val testMe = new FooOuter(inner)
when(inner.stringData(any)).thenReturn("foo")
testMe.dummyCall(1) shouldBe "foobar"
verify(inner).stringData(1)

How to qualify methods as static in Scala?

I have a class
class MyClass {
def apply(myRDD: RDD[String]) {
val rdd2 = myRDD.map(myString => {
// do String manipulation
}
}
}
object MyClass {
}
Since I have a block of code performing one task (the area that says "do String manipulation"), I thought I should break it out into its own method. Since the method is not changing the state of the class, I thought I should make it a static method.
How do I do that?
I thought that you can just pop a method inside the companion object and it would be available as a static class, like this:
object MyClass {
def doStringManipulation(myString: String) = {
// do String manipulation
}
}
but when I try val rdd2 = myRDD.map(myString => { doStringManipulation(myString)}), scala doesn't recognize the method and it forces me to do MyClass.doStringManipulation(myString) in order to call it.
What am I doing wrong?
In Scala there are no static methods: all methods are defined over an object, be it an instance of a class or a singleton, as the one you defined in your question.
As you correctly pointed out, by having a class and an object named in the same way in the same compilation unit you make the object a companion of the class, which means that the two have access to each others' private fields and methods, but this does not mean they are available without specifying which object you are accessing.
What you want to do is either using the long form as mentioned (MyClass.doStringManipulation(myString)) or, if you think it makes sense, you can just import the method in the class' scope, as follows:
import MyClass.doStringManipulation
class MyClass {
def apply(myRDD: RDD[String]): Unit = {
val rdd2 = myRDD.map(doStringManipulation)
}
}
object MyClass {
private def doStringManipulation(myString: String): String = {
???
}
}
As a side note, for the MyClass.apply method, you used the a notation which is going to disappear in the future:
// this is a shorthand for a method that returns `Unit` but is going to disappear
def method(parameter: Type) {
// does things
}
// this means the same, but it's going to stay
// the `=` is enough, even without the explicit return type
// unless, that is, you want to force the method to discard the last value and return `Unit`
def method(parameter: Type): Unit = {
// does things
}
You should follow scala's advice.
val rdd2 = myRDD.map(MyClass.doStringManipulation)
Write this inside the class then it will work as expected.
import MyClass._

Call method in constructor

I have a Controller with a constructor where I´m injecting a cache, but also I would like to invoke a method in the constructor when the instance is created. I know we can create some auxiliary constructors with
def this(foo:Foo){}
But in my case because is play framework the one that instance my bootstrap is a little bit more complex.
Here my code
class SteamController #Inject()(cache: CacheApi) extends BaseController {
private val GAME_IDS_LIST_API: String = "api.steampowered.com/ISteamApps/GetAppList/v2"
private val GAME_API: String = "store.steampowered.com/api/appdetails?appids="
private val GAME_KEY: String = "games"
def games = Action { implicit request =>
var fromRequest = request.getQueryString("from")
if (fromRequest.isEmpty) {
fromRequest = Option("0")
}
val from = Integer.parseInt(fromRequest.get) * 10
val to = from + 10
loadGameIds()
Ok(html.games(SteamStore.gamesIds(cache.getVal[JSONArray](GAME_KEY), from, to), cache.jsonArraySize(GAME_KEY)/10))
}
private def loadGameIds(): Unit = {
val games = cache.get(GAME_KEY)
if (games.isEmpty) {
get(s"$GAME_IDS_LIST_API", asJsonGamesId)
cache.set(GAME_KEY, lastResponse.get, 60.minutes)
}
}
What I would like is that loadGameIds would be invoked and cached when the class is instantiated.
Any suggestion?
Regards.
If I understand correctly your question, you simply want to add some statements to the main constructor body? If that's the case, you can simply do so in the body of the class itself. In your case, that would look like this:
class SteamController #Inject()(cache: CacheApi) extends BaseController {
...
private val GAME_KEY: String = "games"
loadGameIds() // <-- Here we are calling from the main constructor body
def games = Action { implicit request =>
...
}
...
}
When doing so, it is usually a good idea to perform additional code after the declaration of all vals and vars in your class, to ensure they are properly initialized at the time your additional constructor code runs.

Scala inheritance default parameter in parent class

I have an abstract class with a default value for its parameter.
I don't want to have to reuse the default value in the constructor of all the possible implementations.
abstract class Place(val place: String = "World")
class Message(val message: String = "Hello", p: String) extends Place(p) {
override def toString = s"$message $place"
}
What I want to get
new Message("Hi", "Universe") = "Hi Universe" // Ok
new Message("Hi") = "Hi World" // Doesn't work, second parameter is required
new Message() = "Hello World" // Doesn't work, second parameter is required
I considered using an auxiliary constructor omitting the second parameter, but it doesn't help since you can't call super constructors outside of the main constructor.
I want to know how to do it, or why it is not possible. I'm not looking for a workaround, like not using inheritance.
I'm afraid that is not possible. Quite simply, you ARE passing a value to Place constructor, so it wont use the default, whatever its value might be. If you don't mind having a var instead of a val, here is a variant that works for your 3 cases:
abstract class Place(var place: String = "World")
class Message(val message: String = "Hello") extends Place()
{
def this(message: String, place: String) = {
this(message)
this.place = place
}
override def toString = s"$message $place"
}
Constructors in Scala are a little of a mess IMHO. Sometimes a better answer is just to use factory apply() methods on a companion object, which are more flexible.
You can reuse the default value in a more elegant way:
object Place {
val defaultPlace = "World"
}
abstract class Place(val place: String = Place.defaultPlace)
class Message(val message: String = "Hello", p: String = Place.defaultPlace) extends Place(p) {
override def toString = s"$message $place"
}

How to create private fields that my functions will return

My class currently looks like:
class WebConfig(config: Config) {
def this() {
this(ConfigFactor.load())
}
def dbPort = config.getInt("mysql.port")
}
I don't like that when I call dbPort, it has to call and then cast the config each and every time.
So I want to create private fields and set them in the constructor, so then calling dbPort will simply return what a private field has.
How can I do this?
I tried creating a private var but I am getting this error:
class WebConfig(config: Config) {
private var _dbPort: Int
def this() {
this(ConfigFactor.load())
_dbPort = config.getInt("mysql.port")
}
def dbPort: Int = _dbPort
}
Error:
abstract member may not have private modifier
You are getting that error because your private variable is not initially assigned a value, so is treated as abstract, and abstract variables can't be private because they can not be accessed by the sub classes that are required to implement them.
To fix this you can assign a placeholder value to your variable like this:
private var _dbPort: Int = _
That being said, I think vptheron and kululimpa's suggestions are the way to go.
Can't you just write this:
class WebConfig(config: Config) {
def this() {
this(ConfigFactor.load())
}
val dbPort = config.getInt("mysql.port")
}
It will only read the config parameter one time.