Alok
Alok

Reputation: 1506

Initialize variable in Scala Object through some method (similar to init method in class)

I want to implement init method kind of functionality in my object. for ex , my object structure is as follows:

object MyObject {
  var set: Set[String] = _
  var map : Map[String, String] =_
  var list: List[Integer] =_ 
  init()  

  def init() {
    // read external file and initialze variables
    set = ..
    map = ..
    list = .. 
  }
}

I have defined a init method and called init method from object itself. Is this a correct way to do it or can i achieve the same functionality through any better way?

Upvotes: 3

Views: 6458

Answers (2)

Andreas Neumann
Andreas Neumann

Reputation: 10894

General explanation

In Scala the body of the object is the init-Method.

So this is completely equivalent to the version you described above.

object MyObject {
  private[this] val data: List[String] = {List("1","2","3")}

  var mySet: Set[String] = data.toSet
  var myMap: Map[String, String] = data.map(x => (x,x)).toMap
  var list: List[Int] = data.map(_.toInt)
}

and please do not redefine map this will lead to a lot of pain.

Example with external resource:

conf file conf.xml

<config>
  <size>42</size>
</config>

scala object Example.scala

object Example {
  var size : Int =  (XML.loadFile("conf.xml") \\ "size").text.toInt

  println("I am initialized on object creation: >" + size + "<")
}

usage in REPL

scala> :load Example.scala
Loading Example.scala...

import scala.xml.XML
defined object Example

scala> Example
I am initialized on object creation: >42<
res0: Example.type = Example$@3c73951

Upvotes: 2

dhg
dhg

Reputation: 52681

You definitely don't want to have those things as vars, but the good news is you don't have to. How about something like this:

object MyObject {

  private[this] val data: List[String] = {
    // pretend we are reading this from a file
    List("1","2","3")
  }

  val set: Set[String] = data.toSet
  val map: Map[String, String] = data.map(x => (x,x)).toMap
  val list: List[Int] = data.map(_.toInt)
}

If you like having the init() function, you can do something like this (though it's a bit clunkier):

object MyObject {

  private[this] def init() = {
    val data: List[String] = {
      // pretend we are reading this from a file
      List("1","2","3")
    }

    val set = data.toSet
    val map = data.map(x => (x,x)).toMap
    val list = data.map(_.toInt)

    (set, map, list)        
  }

  val (
    set: Set[String],
    map: Map[String, String],
    list: List[Int]) 
      = init()
}

Upvotes: 4

Related Questions