I am developing a desktop application in Scala which has several dozen configuration options that users can configure. The options are defined as a trait so that there can be separate implementations for unit testing and the runtime application:
trait Config { var showNotifications: Boolean var showOverlay: Boolean // ...several dozen similar options } The implementation for unit testing is straightforward:
object TestConfig extends Config { var showNotifications: Boolean = true var showOverlay: Boolean = false // ... } However the implementation for runtime use is more complex because it needs to persist changes and notify various listeners. I define the getters and setters directly to achieve this; each getter and setter refers to a standard method like this:
class UserConfig extends Config { class BooleanPref(val key: String, val default: Boolean) { def get = { // ... load configuration option ... } def set(value: Boolean) = { // ... save configuration option ... } } val prefShowNotifications = new BooleanPref("showNotifications", true) def showNotifications: Boolean = prefShowNotifications.get def showNotifications_=(value: Boolean) = prefShowNotifications.set(value) val prefShowOverlay = new BooleanPref("showOverlay", false) def showOverlay: Boolean = prefShowOverlay.get def showOverlay_=(value: Boolean) = prefShowOverlay.set(value) // ... repeated several dozen times ... } This results in a lot of boilerplate code, which seems like it should be unnecessary. Both the getter and setter have to be mapped individually for each configuration option even though they all work in exactly the same way.
Is there any way in Scala to define both a getter and setter at the same time? ie. instead of having this:
val prefShowNotifications = new BooleanPref("showNotifications", true) def showNotifications: Boolean = prefShowNotifications.get def showNotifications_=(value: Boolean) = prefShowNotifications.set(value) Is it possible to assign an object or function that implements both the getter and setter, something like:
val showNotifications: Boolean = // something here Or is there some other way to avoid defining getters and setters individually?
UserConfigdoesn't store values in the class, it calls an API to record the values externally (for example, in the Windows registry). It wouldn't be suitable to store the values as fields inUserConfigbecause it always needs to look up the latest value from the external API, hence it needs getter and setter methods.ShowNotifications,ShowOverlayetc, then theConfigtrait just has agetand asetmethod?