2013-02-13 231 views
3

這是怎麼回事?爲什麼==比較中的某個位置會改變輸出?爲什麼`foo == bar`和`bar == foo`返回不同的結果?

secret == BCrypt::Password.new(BCrypt::Password.create(secret)) 
# => false 
BCrypt::Password.new(BCrypt::Password.create(secret)) == secret 
# => true 
+0

您是否嘗試過打印出'BCrypt :: Password.new(BCrypt :: Password.create(secret))'的值,或許它們不是您的想法...... – 2013-02-13 00:51:01

回答

3

這是因爲BCrypt::Password.new返回值是BCrypt::Password它覆蓋==

http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009

比較該散列一個潛在的祕密。如果祕密爲原始祕密,則返回true,否則返回false。

所以當secret是在左邊,正在使用它的equals方法(這是做字符串比較),而當散列是在左邊,它實際上是比較反對的隱密

+0

謝謝。我認爲是這樣,但它仍然很混亂。文檔解釋了這一切。我想我會使用.is_password?方法而不是==來避免混淆。 – 2013-02-13 01:08:59

1

最簡單的答案是,==LHS#==,也就是說,這==是不是一個普遍的經營者,像在C或C++或Java,而是調用的對象上的左側功能。

不知道更多關於你的代碼,很難告訴你到底發生了什麼。

簡而言之,secret.class#==的行爲必須與BCrypt::Password#==的行爲不同。也許BCrypt :: Password知道如何比較一個加密的字符串(本身)和一個未加密的字符串(參數),而secret,如果它是一個字符串,不知道如何比較BCrypt::Password自己。

1

BCrypt :: Password有一個==方法來比較祕密。

BCrypt::Password.new(BCrypt::Password.create(secret)).class 
=> BCrypt::Password 

所以

BCrypt::Password.new(BCrypt::Password.create(secret)) == secret 
=> true 

其他表達式不調用該方法==上BCrypt:密碼,但一上線。

http://bcrypt-ruby.rubyforge.org/classes/BCrypt/Password.html#M000009

+1

只是發現Ruby說一切都是一種方法,他們的意思是。來自世界的地方==僅用於表示一件事和一件事。 – 2013-02-13 01:11:28

0

紅寶石是一種面向對象的語言。在OO中,消息發送的接收者可以決定如何響應該消息。在你的情況下,這兩個接收器不僅是不同的對象,它們甚至不同於對象的類型

Ruby中有一些標準的雙重調度協議,旨在確保某些運算符是對稱的,但a)這些協議僅存在於不等於數字的算術運算上,以及b)不能保證對象遵循這些協議。

總之,在OO中,沒有辦法確保運算符的對稱性。這只是面向對象的一個​​基本屬性。

相關問題