diff --git a/core/src/main/scala/magnolia1/impl.scala b/core/src/main/scala/magnolia1/impl.scala index 1d51953..9ab2fc3 100644 --- a/core/src/main/scala/magnolia1/impl.scala +++ b/core/src/main/scala/magnolia1/impl.scala @@ -114,8 +114,8 @@ object CaseClassDerivation: override def apply(): Option[p] = defaults.get(label).flatten.flatMap(d => unsafeCast(d.apply)) paramFromMaps[Typeclass, A, p]( label, - new CallByNeed(tc), - new CallByNeed(d, () => true), + CallByNeed.createLazy(tc), + CallByNeed.createValueEvaluator(d), repeated, annotations, inheritedAnnotations, @@ -203,7 +203,7 @@ trait SealedTraitDerivation: IArray.from(paramTypeAnns[A]), isObject[s], idx, - new CallByNeed(tc), + CallByNeed.createLazy(tc), isType, asType ) diff --git a/core/src/main/scala/magnolia1/interface.scala b/core/src/main/scala/magnolia1/interface.scala index 57453c8..a85c0da 100644 --- a/core/src/main/scala/magnolia1/interface.scala +++ b/core/src/main/scala/magnolia1/interface.scala @@ -363,17 +363,32 @@ object CallByNeed: /** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only * happen once. */ + def createLazy[A](a: () => A): CallByNeed[A] = new CallByNeed(a, () => false) + + /** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only + * happen once. + * + * If by-name parameter causes serialization issue, use [[createLazy]]. + */ def apply[A](a: => A): CallByNeed[A] = new CallByNeed(() => a, () => false) /** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only * happen once. Evaluation of a value via `.valueEvaluator.map(evaluator => evaluator())` will happen every time the evaluator is called */ + def createValueEvaluator[A](a: () => A): CallByNeed[A] = new CallByNeed(a, () => true) + + /** Initializes a class that allows for suspending evaluation of a value until it is needed. Evaluation of a value via `.value` can only + * happen once. Evaluation of a value via `.valueEvaluator.map(evaluator => evaluator())` will happen every time the evaluator is called + * + * If by-name parameter causes serialization issue, use [[withValueEvaluator]]. + */ def withValueEvaluator[A](a: => A): CallByNeed[A] = new CallByNeed(() => a, () => true) end CallByNeed // Both params are later nullified to reduce overhead and increase performance. // The supportDynamicValueEvaluation is passed as a function so that it can be nullified. Otherwise, there is no need for the function value. -final class CallByNeed[+A](private[this] var eval: () => A, private var supportDynamicValueEvaluation: () => Boolean) extends Serializable { +final class CallByNeed[+A] private (private[this] var eval: () => A, private var supportDynamicValueEvaluation: () => Boolean) + extends Serializable { // This second constructor is necessary to support backwards compatibility for v1.3.6 and earlier def this(eval: () => A) = this(eval, () => false)