为什么`foo == bar`和`bar == foo`会返回不同的结果?

时间:2013-02-13 00:44:59

标签: ruby

这里发生了什么?为什么==比较中的边位置会改变输出?

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

4 个答案:

答案 0 :(得分:3)

这是因为BCrypt::Password.new的返回值为BCrypt::Password,它会覆盖==

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

  

将潜在的秘密与哈希进行比较。如果是,则返回true   秘密是原始的秘密,否则就是假的。

所以当secret在左边时,正在使用它的equals方法(正在进行字符串比较),而当哈希在左边时,它实际上是与原始秘密进行比较

答案 1 :(得分:1)

最简单的答案是==LHS#==,也就是说,==不是通用运算符,就像在C或C ++或Java中一样,而是一个被调用的函数在左侧的物体上。

在不了解您的代码的情况下,很难准确地告诉您发生了什么。

简单来说,secret.class#==的行为必须与BCrypt::Password#==不同。也许BCrypt :: Password知道如何比较加密的字符串(本身)和未加密的字符串(参数),而secret,如果是字符串,则不知道如何将BCrypt::Password与自身进行比较

答案 2 :(得分:1)

BCrypt ::密码有一个==方法与秘密进行比较。

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

所以

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

另一个表达式不会在BCrypt :: Password上调用方法==,而是调用字符串上的方法。

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

答案 3 :(得分:0)

Ruby是一种面向对象的语言。在OO中,消息发送的接收者决定如何响应该消息。在您的情况下,两个接收器不仅是不同的对象,它们甚至是对象的类型

Ruby中有一些标准的双调度协议,旨在确保某些运算符是对称的,但是a)这些协议仅存在于数字上的算术运算而不是相等,并且b)不保证对象遵循那些协议。

简而言之,在OO中,无法确保运营商的对称性。这只是OO的基本属性。