8

I would to make the second constructor argument optional, and use the value of the first argument in that case. Is there any way I can do that ? This code doesn't compile as it can't find realUser:

class CurrentUser(val realUser:String, val masqueradeUser:String = realUser)

I'm sure I can work around it by writing my own constructor, but I wondered if there were a more concise way. Actually now that I've tried writing my own constructor, it isn't that bad:

class CurrentUser(val realUser:String, val masqueradeUser:String) {
    def this(realUser:String) = this(realUser, realUser)
}

If someone can come up with something shorter then great, otherwise I'll post my own answer.

Nick
  • 11,475
  • 1
  • 36
  • 47

3 Answers3

11

I believe your solution with the auxiliary constructor is the better one. A parameter is not visible in its own parameter list, only in the following ones. So you would have to do

class CurrentUser(val realUser: String)(val masqueradeUser: String = realUser)

and then call with

new CurrentUser(real)()

Not too nice.

Didier Dupont
  • 29,398
  • 7
  • 71
  • 90
  • Cool - I've never really used multiple parameter lists before. You're correct that perhaps this isn't the place to use them though :) – Nick Oct 20 '11 at 10:47
8

You can’t reuse parameters from the same parameter list as default arguments. didierd’s solution works, and probably your solution with a second constructor is the most elegant. Here's a third alternative, which uses the dreaded null:

scala> class CurrentUser(val realUser:String, _masqueradeUser: String = null) {
     |   val masqueradeUser = if (_masqueradeUser == null) realUser else _masqueradeUser
     | }
defined class CurrentUser

scala> new CurrentUser("paul").masqueradeUser
res1: String = paul

scala> new CurrentUser("paul", "p").masqueradeUser
res2: String = p

If you want to avoid null, you can use the Opt[A] class discussed here if you don't mind the overhead. One way or another, I’d still go with your second-constructor solution.

Community
  • 1
  • 1
Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
5

Thanks for the suggestions. I think I will stick with specifying the second constructor form manually. Here it is as an answer for completeness' sake.

class CurrentUser(val realUser:String, val masqueradeUser:String) {
    def this(realUser:String) = this(realUser, realUser)
}
Nick
  • 11,475
  • 1
  • 36
  • 47