-
Notifications
You must be signed in to change notification settings - Fork 174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Case class instance unexpectedly shared across map entries #1329
Comments
I'd go so far as to say that we hadn't considered what the expected
behavior of that impure operation would be in pureconfig.
Do you get different behavior if you define your configuration like:
```
case class AnotherConf(a: InnerConfig, b: InnerConfig)
```
And your config string like:
```
"{a {}, b: {} }"
```
?
…On Mon, Jun 13, 2022 at 1:47 PM Arne Gebert ***@***.***> wrote:
import pureconfig._
import pureconfig.generic.auto._
case class InnerConf() {
lazy val value = {
val value2 = scala.util.Random.nextInt(1000000)
println(s"InnerConf has following value: $value2")
value2
}
}
case class OuterConf(middle: Map[String, MiddleConf] = Map.empty)
case class MiddleConf(inner: InnerConf = InnerConf()) {
println(s"inner-value: ${inner.value}, inner-hashcode ${inner.hashCode()}")
}
val res = ConfigSource.string("{middle.1 {}, middle.2 {}}").load[OuterConf]
Expectation: two separate instances of case class InnerConf are generated
Reality: the same instance of InnerConf is reused across the map entries
"1" and "2" of middle
Example output:
InnerConf has following value: 51556
inner-value: 51556, inner-hashcode 2141524893
inner-value: 51556, inner-hashcode 2141524893
Is this intended behaviour? In my use case, I have a case class
representing a random key-pair instead of InnerConf, and I would like to
generate a random value when inner is not specified. I was surprised when
the same object was being reused.
Apologies if there is a simpler way to reproduce the behaviour.
—
Reply to this email directly, view it on GitHub
<#1329>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFSTZT7BNQTPSIZEVJFNVDVO6F5ZANCNFSM5YVJ6HLA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
This is related to #1218. For default values, generic derivation using shapeless relies on a If you're OK with not using generic derivation for import pureconfig._
import pureconfig.generic.auto._
case class InnerConf() {
lazy val value = {
val value2 = scala.util.Random.nextInt(1000000)
println(s"InnerConf has following value: $value2")
value2
}
}
case class OuterConf(middle: Map[String, MiddleConf] = Map.empty)
case class MiddleConf(inner: InnerConf = InnerConf()) {
println(s"inner-value: ${inner.value}, inner-hashcode ${inner.hashCode()}")
}
object MiddleConf {
implicit val middleConfReader: ConfigReader[MiddleConf] =
ConfigReader.forProduct1[MiddleConf, Option[InnerConf]]("inner")(_.fold(MiddleConf())(MiddleConf(_)))
}
val res = ConfigSource.string("{middle.1 {}, middle.2 {}}").load[OuterConf] However, my recommendation would be to avoid impure logic when loading the config. For your use case that means keeping your config domain models pure and handle the generation of random key-pairs separately. |
Thanks a lot for the clarifications! In my case, the easiest (backwards-compatible) solution I found is declaring
Example output:
Apologies for the delayed response. From my side, this issue is resolved and it could be closed. |
Expectation: two separate instances of case class
InnerConf
are generatedReality: the same instance of
InnerConf
is reused across the map entries "1" and "2" ofmiddle
Example output:
Is this intended behaviour? In my use case, I have a case class representing a random key-pair instead of
InnerConf
, and I would like to generate a random value wheninner
is not specified. I was surprised when the same object was being reused.Apologies if there is a simpler way to reproduce the behaviour.
The text was updated successfully, but these errors were encountered: