2013-02-13 129 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中,没有办法确保运算符的对称性。这只是面向对象的一个​​基本属性。

相关问题