2017-07-01 6 views
0

ユーザパスワードの暗号化にScala bCrypt wrapperを使用しています。このラッパーは暗黙のクラスを提供します。Scala暗黙のクラスメンバにオブジェクト内でアクセスできない

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() 
} 

しかし、私はクラスにこの暗黙converisionを使用していたときに私はそれがオブジェクトまたはケースクラスと罰金が、converiosn doesntの仕事をworkes、奇妙な問題に直面しています。

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> 

ここで間違っていることはわかりません。

答えて

2

安定した識別子シャドウは、implicit識別子をインポートしました。暗黙の暗黙の可能性があるものには、val,def,objectおよび生成されたコンパニオンオブジェクトcase classが含まれます。単純classtypeは識別子を作成しないので、インポートされたimplicit識別子をシャドーしません。

implicit class Passwordclass Passwordimplicit def Passwordのためだけ糖衣構文で、そのためPasswordという名前あなたのコード内の識別子は、そのimplicit defシャドウでしょう。

object Foo { 
    import bcrypt._ 
    class Password() 
    "123".bcrypt 
} 

次のスニペットのすべてのコンパイルに失敗します:

object Foo2 { 
    import bcrypt._ 
    val Password = 1 
    "123".bcrypt 
} 

object Foo3 { 
    import bcrypt._ 
    def Password() = 1 
    "123".bcrypt 
} 

object Foo4 { 
    import bcrypt._ 
    case class Password() 
    "123".bcrypt 
} 

object Foo5 { 
    import bcrypt._ 
    object Password 
    "123".bcrypt 
} 

あなたのケースでは解決は簡単です:このコードはOKコンパイルしながら、だから、

何か他のものへの暗黙のクラスの名前を変更それは他の識別子と衝突することはまずありません。たとえば、implicit class PasswordExtensionsです。

あなたは元のコードでimplicit classの名前を変更することができない場合は、別の名前で輸入それを行うことができますimport com.github.t3hnar.bcrypt.{Password => PasswordExtensions, _}

+0

オクラホマので、識別子がこれを引き起こしていたとして、それは「パスワード」の衝突だっ判明この文を変更するだけで動作しますimport com.github.t3hnar.bcrypt。{Password => BcryptUtil} –

関連する問題