I am using Scala bCrypt wrapper for encrypting user password, this wrapper provides an implicit class.
package object bcrypt {
implicit class Password(val pswrd: String) extends AnyVal {
def bcrypt: String = B.hashpw(pswrd, BCrypt.gensalt())
def bcrypt(rounds: Int): String = B.hashpw(pswrd, BCrypt.gensalt(rounds))
def bcrypt(salt: String): String = B.hashpw(pswrd, salt)
def isBcrypted(hash: String): Boolean = B.checkpw(pswrd, hash)
}
def generateSalt: String = B.gensalt()
}
But I am facing a strange problem, whenever I am using this Implicit converision in class it workes fine but converiosn doesnt work with object or case classes.
scala> import com.github.t3hnar.bcrypt._
import com.github.t3hnar.bcrypt._
scala> class Password(secret: String) {
| def validate(userSecret: String): Boolean = userSecret.isBcrypted(secret)
|
| override def toString = secret
| }
defined class Password
scala> object Password {
| def apply(secret: String): Password = new Password(secret)
|
| def getEncrypted(secret: String) = new Password(secret.bcrypt)
| }
<console>:18: error: value bcrypt is not a member of String
def getEncrypted(secret: String) = new Password(secret.bcrypt)
^
scala>
I am not sure what I am doing wrong here.
Any stable identifier shadows imported
implicitidentifiers. Things that can shadow implicits includeval,def,objectand the generated companion object ofcase class. Simpleclasses andtypes don't create identifiers and thus don't shadow importedimplicitidentifiers.implicit class Passwordis just syntactic sugar for aclass Passwordand animplicit def Password, and so an identifier in your code namedPasswordwould shadow thatimplicit def.So while this code compiles OK:
All of the following snippets will fail to compile:
The solution in your case is simple: rename the implicit class to something else, that would be unlikely to clash with other identifiers. For example,
implicit class PasswordExtensions.If you can't rename the
implicit classin the original code, you can import it under a different name:import com.github.t3hnar.bcrypt.{Password => PasswordExtensions, _}