ここで何が起こっているのですか?==
比較して辺の位置が出力を変更するのはなぜですか?
secret == BCrypt::Password.new(BCrypt::Password.create(secret))
# => false
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
# => true
ここで何が起こっているのですか?==
比較して辺の位置が出力を変更するのはなぜですか?
secret == BCrypt::Password.new(BCrypt::Password.create(secret))
# => false
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
# => true
これは、の戻り値がBCrypt::Password.new
オーバーライドBCrypt::Password
されるためです。==
http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009
潜在的な秘密をハッシュと比較します。シークレットが元のシークレットの場合はtrueを返し、そうでない場合はfalseを返します。
したがって、secret
が左側にある場合は、equalsメソッドが使用され(文字列比較を実行します)、ハッシュが左側にある場合は、実際には元のシークレットと比較されます。
最も簡単な答えは==
、LHS#==
つまり==
、C、C ++、Javaのような普遍的な演算子ではなく、左側のオブジェクトで呼び出される関数です。
コードについて詳しく知らなければ、何が起こっているのかを正確に伝えることは困難です。
簡単に言うと、secret.class#==
はとは異なる動作をする必要がありますBCrypt::Password#==
。おそらく、BCrypt :: Passwordは、暗号化された文字列(それ自体)と暗号化されていない文字列(引数)を比較する方法を知っていますがsecret
、文字列の場合は、それ自体と比較BCrypt::Password
する方法を知りません。
BCrypt :: Passwordには、シークレットと比較するための==メソッドがあります。
BCrypt::Password.new(BCrypt::Password.create(secret)).class
=> BCrypt::Password
それで
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret
=> true
もう1つの式は、BCrypt :: Passwordのメソッド==を呼び出しませんが、文字列のメソッドを呼び出します。
http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009
Rubyはオブジェクト指向言語です。OOでは、メッセージ送信の受信者は、そのメッセージへの応答方法を決定します。あなたの場合、2つのレシーバーは異なるオブジェクトであるだけでなく、異なるタイプのオブジェクトでもあります。
Rubyには、一部の演算子が対称であることを保証することを目的とした標準のダブルディスパッチプロトコルがいくつかありますが、これらのプロトコルは、等式ではなく数値の算術演算にのみ存在し、b)オブジェクトがこれらのプロトコルに従うという保証はありません。
つまり、OOでは、演算子の対称性を保証する方法はありません。これはOOの基本的な特性です。