balteo
balteo

Reputation: 24679

Are casts possible in scala

I have the following method:

 def generateTokenForAccount(account: Account): Account = {
    account.setAccountToken(UUID.randomUUID().toString())
    return account
  }

I am passing to this method a subclass of Account i.e. ChildminderAccount and I am trying to cast the result in scala to no avail. What I am getting wrong?

@Transactional
  def registerChildminderAccount(childminderAccount: ChildminderAccount): Boolean = {
    childminderAccountDAO.save((ChildminderAccount) generateTokenForAccount(childminderAccount))//problem here!!
    if (mailerService.requestChildminderConfirmation(childminderAccount)) {
      return true
    } else {
      return false
    }
  }

I get the following error: value generateTokenForAccount is not a member of object com.bignibou.domain.ChildminderAccount as if I was invoking the generateTokenForAccount on the ChildminderAccount class.

Can anyone please help?

Upvotes: 1

Views: 777

Answers (4)

Dan Burton
Dan Burton

Reputation: 53705

Why does the generateTokenForAccount return its input? This is deceptive, because it leads you to believe that it constructs a new, modified object, when in fact it does not; instead it mutates the object passed in. It should return Unit to indicate this:

def generateTokenForAccount(account: Account) {
  account.setAccountToken(UUID.randomUUID().toString())
}

Now the type guides you to see that you can simply use the effect in sequence:

def registerChildminderAccount(childminderAccount: ChildminderAccount): Boolean = {
    generateTokenForAccount(childminderAccount)
    childminderAccountDAO.save(childminderAccount)
    mailerService.requestChildminderConfirmation(childminderAccount)
  }

Also, whenever you have if foo { return true } else { return false }, this is equivalent to return foo. In Scala, the last expression in a block is automatically returned, so you can even remove the return keyword.

Upvotes: 0

Travis Brown
Travis Brown

Reputation: 139048

You can use a cast here, but in general in Scala asInstanceOf is a code smell (as is return). Try the following instead:

def generateTokenForAccount[A <: Account](account: A): A = {
  account.setAccountToken(UUID.randomUUID.toString)
  account
}

Now if you put in a ChildminderAccount you'll get out a ChildminderAccount.

Upvotes: 10

andy
andy

Reputation: 1715

May want to use 'match' for better error handling

generateTokenForAccount(childminderAccount) match {
  case acc: ChildminderAccount => childminderAccountDAO.save( acc )
  case _ => // ERROR
}

Upvotes: 4

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340883

generateTokenForAccount(childminderAccount).asInstanceOf[ChildminderAccount]

Upvotes: 4

Related Questions