I often encounter the situation where I have a factory method for some trait and the names of the arguments clash with the members of the trait causing them to be hidden:
trait MyTrait {
val a: Int
val b: String
}
object MyTrait {
def apply(a: Int, b: String): MyTrait = new MyTrait {
val a = a // Recursive infinite loop.
val b = b
}
}
So usually I have to do something ugly like:
def apply(aA: Int, bB: String): MyTrait = new MyTrait {
val a = aA
val b = bB
}
or make local copies of the arguments:
def apply(a: Int, b: String): MyTrait = {
val localA = a
val localB = b
new MyTrait {
val a = localA
val b = localB
}
I would like the parameters to the apply
method to be the same as the members of my trait, so that client code reads nicely when I used named parameters: e.g. MyTrait(a=3,b="123")
.
Is there a neater mechanism that lets me capture the outer scope where the argument parameters are defined, but the anonymous class isn't yet? For example something like:
def apply(a: Int, b: String): MyTrait = { outer =>
new MyTrait {
val a = outer.a
val b = outer.b
}
}
Thanks!
If we need to create an instance, why not delegate it to the constructor. So I can think of this hack:
trait MyTrait {
def a: Int
def b: String
}
object MyTrait {
private class MkMyTrait(val a: Int, val b: String) extends MyTrait
def apply(a: Int, b: String): MyTrait = new MkMyTrait(a, b)
}
My answer to the dupe, which doesn't save much:
trait T { val t: Int }
object T {
def apply(t: Int): T = new {
private[this] val x = t
} with T {
val t = x
}
}
Also, -optimise doesn't get rid of the field.
Here's a different idea: alias the param name.
Soon, we'll be able to filter warnings selectively, so it will be possible to ignore the warning that is generated when deprecation is enabled:
scala> :pa
// Entering paste mode (ctrl-D to finish)
trait T { val t: Int }
object T {
def apply(@deprecatedName('t) t0: Int): T = new T { val t = t0 }
}
// Exiting paste mode, now interpreting.
defined trait T
defined object T
scala> T(t = 42)
warning: there was one deprecation warning; re-run with -deprecation for details
res1: T = T$$anon$1@6ea1bcdc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With