I have this piece of code that loads Properties from a file:
class Config {
val properties: Properties = {
val p = new Properties()
p.load(Thread.currentThread().getContextClassLoader.getResourceAsStream("props"))
p
}
val forumId = properties.get("forum_id")
}
This seems to be working fine.
I have tried moving the initialization of properties into another val, loadedProperties, like this:
class Config {
val properties: Properties = loadedProps
val forumId = properties.get("forum_id")
private val loadedProps = {
val p = new Properties()
p.load(Thread.currentThread().getContextClassLoader.getResourceAsStream("props"))
p
}
}
But it doesn’t work! (properties is null in properties.get("forum_id") ).
Why would that be? Isn’t loadedProps evaluated when referenced by properties?
Secondly, is this a good way to initialize variables that require non-trivial processing? In Java, I would declare them final fields, and do the initialization-related operations in the constructor.
Is there a pattern for this scenario in Scala?
Thank you!
Vals are initialized in the order they are declared (well, precisely, non-lazy vals are), so
propertiesis getting initialized beforeloadedProps. Or in other words,loadedPropsis stillnullwhenpropertiesis getting initialized.The simplest solution here is to define
loadedPropsbeforeproperties:You could also make
loadedPropslazy, meaning that it will be initialized on its first access:Using lazy val has the advantage that your code is more robust to refactoring, as merely changing the declaration order of your vals won’t break your code.
Also in this particular occurence, you can just turn
loadedPropsinto adef(as suggested by @NIA) as it is only used once anyway.