8

I'm trying to create a singleton object with parameters which are specified by runtime. Example:

object NetworkPusher {
  val networkAdress = ???
  ...
 }

Imagine the networkAdress param comes from the command-line. How can I make a workaround to do this?

1
  • 1
    AFAIK, you cannot do this. Object definitions need to be completely specified at compile time. However, if you want to just set the value of the network address from the command line args, you can use the args array and pass in the value of of the network address in the NetworkPusher constructor. Commented Jan 6, 2015 at 15:31

3 Answers 3

10

Singletons are initialized lazily.

scala> :pa
// Entering paste mode (ctrl-D to finish)

object Net {
  val address = Config.address
}
object Config { var address = 0L }

// Exiting paste mode, now interpreting.

defined object Net
defined object Config

scala> Config.address = "1234".toLong
Config.address: Long = 1234

scala> Net.address
res0: Long = 1234

FWIW.

Sign up to request clarification or add additional context in comments.

1 Comment

I never knew about :pa paste mode! Great tip!
0

This is rather convention over configuration approach. But it is thread safe and adds obligatory initialisation requirement:


    abstract class NetworkPusher() {
      private var networkAddress: String = ""
      def setNetworkAddr(addr: String) = networkAddress = addr
      def getNetworkAddr() = networkAddress
    }

    object NetworkPusherFactory {
    
      private var initOnceReady: NetworkPusher => Unit = _
    
      private lazy val initializedInstance = {
        val pusher =  new NetworkPusher(){}
        initOnceReady(pusher)
        pusher
      }
      def create(init: NetworkPusher => Unit): NetworkPusher = {
        initOnceReady = init
        initializedInstance
      }
    }
    
    object Main {
      def main(args: Array[String]): Unit = {
        val networkAddr = "A.D.D.R" // args[0]
        val onePusher = NetworkPusherFactory.create(
          instance => instance.setNetworkAddr(networkAddr)
        )
        println(s"using ${onePusher.getNetworkAddr}")
      }
    }

Comments

-1

Using lazy:

object Program {

  var networkAdress: String = _

  def main(args: Array[String]): Unit = {
    networkAdress = args(0)
    println(NetworkPusher.networkAdress)
  }

  object NetworkPusher {
    lazy val networkAdress = Program.networkAdress
  }
}

1 Comment

lazy here is not needed, object is initialized lazily

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.