Reputation: 6884
I have a class like this:
class A(arg: Int)(implicit i: Boolean) {
def apply(v: Double): this.type = {
// do stuff
this
}
}
and I want to create an instance of it by both initializing it and calling apply in the same line:
implicit val i = false
val a = A(arg=1)(v=2.0) // doesn't work
val a2 = (A(arg=1))(v=2.0) // doesn't work
Unfortunately the compiler assumes that v=2.0 is meant for the implicit parameter instead of being for the apply(). I tried a number of different syntaxes with inserting {}'s and ()'s, but none of them worked. I realize that v could be moved into the constructor, but in my case that isn't an option because A is subclassed and I don't want to add v to every subclass constructor. Is there a way to achieve this? Thanks.
Upvotes: 3
Views: 609
Reputation: 59994
(I assume you have a constructor method in the companion object as you're not using new A
.)
An option is to write it on two lines:
val atmp = A(1)
val a = atmp(2.0)
… but that's certainly not what you're after. Another equally dissatisfying option would be
val a = A(1)(implicitly)(2.0)
if you can live with that. Maybe the least ugly way to do it is to call apply
explicitly:
val a = A(1).apply(2.0)
Lastly, you could add a new constructor method to the companion object that takes care of it all:
object A {
def apply(arg: Int, v: Double)(implicit i: Boolean) = A(arg)(i)(v)
}
val a = A(1, 2.0)
Upvotes: 4
Reputation:
How about "ugly but it seems to work"...
class A(arg: Int)(implicit i: Boolean) {
def apply(v: Double): this.type = this
}
implicit val i = false
// removing the :A makes this fail to run on simplyscala
val a1 = (new A(arg=1) : A)(v=2.0)
// also works with explicit method name
val a2 = new A(arg=1).apply(v=2.0)
// and works without implicit being ... implicitized
val a = new A(arg=1)(i)(v=2.0)
Honestly, no idea :-) However, consider this which might be some insight:
val a = (new A(arg=1))(2.0)
error: type mismatch; found : Double(2.0) required: Boolean val a = (new A(arg=1))(2.0)
Whoa!
Happy coding.
Upvotes: 5