等式运算符的顺序在Ruby中重要吗?
我在Ruby程序中使用了bcrypt库。我注意到相等运算符的顺序似乎很重要。根据哪个变量在“==”的左边或右边,我会得到不同的结果。 以下是一个示例程序:等式运算符的顺序在Ruby中重要吗?,ruby,operators,bcrypt,equality,commutativity,Ruby,Operators,Bcrypt,Equality,Commutativity,我在Ruby程序中使用了bcrypt库。我注意到相等运算符的顺序似乎很重要。根据哪个变量在“==”的左边或右边,我会得到不同的结果。 以下是一个示例程序: require 'bcrypt' my_pw = "pw1" puts "This is my unhashed password: #{my_pw}" hashed_pw = BCrypt::Password.create(my_pw) puts "This is my hashed pas
require 'bcrypt'
my_pw = "pw1"
puts "This is my unhashed password: #{my_pw}"
hashed_pw = BCrypt::Password.create(my_pw)
puts "This is my hashed password: #{hashed_pw}"
20.times{print"-"}
puts
puts "my_pw == hashed_pw equals:"
if (my_pw == hashed_pw)
puts "TRUE"
else
puts "FALSE"
end
puts "hashed_pw == my_pw equals:"
if (hashed_pw == my_pw)
puts "TRUE"
else
puts "FALSE"
end
问候
schande例如,如果两个操作数都是字符串类型,则表达式将是等效的。在本例中,一个操作数是
字符串
,另一个是BCrypt::Password
。因此,my_pw==hashed_pw
调用String类中定义的相等方法,而hashed_pw==my_pw
调用BCrypt::Password中定义的相等方法
我从未使用过BCrypt::Password,但希望前者得到
false
,后者得到true
。如果两个操作数都是字符串类型,则表达式将是等效的。在本例中,一个操作数是字符串
,另一个是BCrypt::Password
。因此,my_pw==hashed_pw
调用String类中定义的相等方法,而hashed_pw==my_pw
调用BCrypt::Password中定义的相等方法
我从未使用过BCrypt::Password,但我希望前者得到
false
,后者得到true
。在Ruby中,您可以覆盖给定类或实例的相等方法:
class Test
define_method(:==) do |_other|
true
end
end
Test.new == 'foo' # => true
Test.new == nil # => true
Test.new == 42 # => true
'foo' == Test.new # => false
nil == Test.new # => false
42 == Test.new # => true
一般来说,重写相等而不使其对称被认为是不好的做法,但您有时会在野外看到它。在Ruby中,您可以重写给定类或实例的相等方法:
class Test
define_method(:==) do |_other|
true
end
end
Test.new == 'foo' # => true
Test.new == nil # => true
Test.new == 42 # => true
'foo' == Test.new # => false
nil == Test.new # => false
42 == Test.new # => true
一般来说,忽略等式而不使其对称被认为是不好的做法,但你有时会在野外看到它。是的,这是有区别的
my_pw==hashed_pw
调用my_pw
字符串上的=
方法,并将hashed_pw
作为参数传递。这意味着您正在使用String#=
方法。从:
如果对象
具有相同的长度和内容,则返回true
;作为self
<代码>错误否则
而hashed_pw==my_pw
在BCrypt::Password
的实例上调用=
方法,并将my_pw
作为参数传递。从以下文件:
将潜在机密与哈希进行比较。如果机密是原始机密,则返回true
,否则返回false
是的,有区别
my_pw==hashed_pw
调用my_pw
字符串上的=
方法,并将hashed_pw
作为参数传递。这意味着您正在使用String#=
方法。从:
如果对象
具有相同的长度和内容,则返回true
;作为self
<代码>错误否则
而hashed_pw==my_pw
在BCrypt::Password
的实例上调用=
方法,并将my_pw
作为参数传递。从以下文件:
将潜在机密与哈希进行比较。如果机密是原始机密,则返回true
,否则返回false
这与平等没有任何关系。这只是面向对象编程的基础 在OOP中,所有计算都是由对象向其他对象发送消息来完成的。OOP的一个基本属性是接收方对象,并且只有接收方对象决定如何响应此消息。这就是在OOP中实现封装、数据隐藏和抽象的方式 因此,如果将消息
m
发送到对象a
并将b
作为参数传递,则a
将决定如何解释此消息。如果将消息m
发送到对象b
并将a
作为参数传递,则由b
决定如何解释此消息。没有任何内置机制可以保证a
和b
对该消息的解释相同。只有当这两个对象决定相互协调时,响应才会真正相同
如果你想一想,如果2-3
和3-2
有相同的结果,那将是非常奇怪的
这正是此处发生的情况:在第一个示例中,您将消息==
发送到my_pw
,并将哈希_pw
作为参数传递my_pw
是的一个实例,因此=
消息将被发送到该方法。此方法知道如何将接收器对象与另一个字符串
进行比较。然而,它不知道如何将接收器与a进行比较,这就是hashed_pw的类
如果你仔细想想,这是有道理的:BCrypt::Password
是Ruby之外的第三方类,一个内置Ruby类怎么知道在实现String
类时根本不存在的东西呢
另一方面,在第二个示例中,您将消息==
发送到散列\u pw
,并将my\u pw
作为参数传递。此消息被发送到方法,该方法不知道如何将接收方与字符串进行比较:
方法:BCrypt::Password#==
在中定义:lib/bcrypt/password.rb
#==(秘密)
⇒ <代码>对象
也称为:
是密码吗?
将潜在机密与哈希进行比较。如果机密是原始机密,则返回true
,否则返回false
事实上,这个特殊情况下的问题甚至比最初出现的问题更微妙
我在上面写道,String#=
不允许
#==(secret) ⇒ Object