我的理解是,在Ruby编程语言中,只有nil
和false
被认为是false
,其他一切都被认为是真的。
因此,1 == true
应该返回true
。
我正在使用MS SQL Server(布尔字段,tinyint(1))处理Rails 4.0.2项目,并且无法使布尔值正常工作。数据库列中的值为1
。
难倒,我开始在控制台中测试一些东西。这是我在Rails控制台中得到的内容:
1 == true # => false
0 == true # => false
"test" == true # => false
"" == true # => false
为什么所有内容都注册为false
?我以为他们都应该是true
?
我最终必须通过<attribute>.to_i == 1
进行布尔检查以获得有效的真/假值。
我是否遗漏了Ruby语言中的内容,还是在某些我不知道的版本中更新了?我在Mac机器上使用RVM ruby 2.0.0p481 (2014-05-08 revision 45883)
。
更新时间:2014-10-28 09:00
在阅读下面的优秀答案后,我明白我的想法是错误的。
我认为其中一个问题是我使用的大多数数据库适配器(PostgreSQL,MySQL等等)都在DB中为我转换了布尔值。
例如,在我的很多代码库中我都有:
# User has an :admin boolean attribute
class User < ActiveRecord::Base
def admin?
admin == true
end
end
我怀疑这个工作“很好”,因为DB适配器负责将DB值转换为适合我的布尔值。
但是,我目前正在开发一个项目,我需要使用MS SQL Server,而且我遇到了很多使用数据库适配器的“陷阱”,其中一个是我不相信它对待布尔字段与其他适配器相同。
因此,我一直认为任何TRUTHY值都等于true
,而不是rspec
。我想这就是为什么be_truthy
和其他人已经开始在他们自己的语法中使用be_true
而不是纯粹的{{1}}。
我很惊讶在我遇到这样的问题之前花了几年时间!
答案 0 :(得分:3)
我的理解是,在Ruby编程语言中,只有nil和false被认为是假的,而其他一切都被认为是真的
这是事实。
然而,
&#34;因此,1 == true应该返回true。&#34;
是假的。
说明:在Ruby中,除false / nil之外的所有内容都被认为是真的。 然而在测试相等性时,例如x == true
您实际上没有测试&#34;此值是否为真&#34;但是&#34;这个值等于为真&#34;。
当然1
不等于true
,1
是一个数字,true
是一个布尔值。你可以在&#34; Ruby Equality And Object Comparison&#34;
如果你真的,真的想以这种方式测试它,你需要将像1
这样的表达式转换为它的布尔值,你可以通过双重否定它来做。所以!!1 # => true
。
因此,您的示例将如下所示:
!!1 == true # => true
!!0 == true # => true
!!"test" == true # => true
!!"" == true # => true
但是我认为在大多数情况下都没有必要。
使用MSSQL时,您应该让Active Record为您完成所有转换。在迁移中声明字段,类型为boolean,当您在数据库中进行where
搜索时,请执行以下操作:
Model.where(['attribute = ?', true])
Model.where(:attribute=> true)
这样,ActiveRecord将完成与将类型转换为兼容数据库相关的所有相关工作。
答案 1 :(得分:1)
就逻辑谓词而言,除nil
和false
之外的每个对象都是 TRUTHY 。什么基本上意味着将执行对应我们的谓词(条件)的语句。
虽然nil
和false
是 FALSEY 谓词。
在实践中,它意味着:
if predicate
statement_a
else
statement_b
end
除了nil
和false
statement_a
之外,任何谓词都不会被执行。否则statement_b
将获得千斤顶。
答案 2 :(得分:0)
首先,假设Ruby中的所有内容都不为假或为零,我认为是真的。
让我们来看看你的四个例子:
1 == true # => false
在评估此表达式时,Ruby获取第一个参数的类,查找运算符方法并进行求值。因此,对于Fixnums,它会评估1是否等于另一个数字编号。 Fixnum#== docs相当于1。
0 == true # => false
与上述相同。
"test" == true # => false
这是通过String类进行的相等测试。如String#== docs中所述,该类在右侧进行测试,如果它不是字符串,但是响应to_str
(true确实如此),那么Object#===方法是使用和评估询问两者是否是同一个对象,这不是这里的情况。
"" == true # => false
这与上述相同。
Esse的回答是正确的,表明除false和nil之外的所有对象都是真的。
!!false # => false
!!nil # => false
答案 3 :(得分:0)
==
就像Ruby中的任何其他方法一样,类用来决定传递的参数(右侧的参数)是否等于它的对象,就像你可以定义一样您自己的==
方法。实际上,如果您愿意,甚至可以修改==
方法适用于任何Ruby基本对象的方式,例如Fixnum
。
所以当你说1 == true
你实际上说的是1.==(true)
时,在这种情况下,类Fixnum
不喜欢将传递的参数true
视为相等到它的对象1
。
现在当你说除了nil
和false
之外的所有内容都被认为是真的,正确的说法是在Ruby中只有false
和nil
是 falsey ,其他一切都是 truthy 。因此,当Ruby必须决定某个值或对象计为或计算为真时(例如在if语句中:if ('test')
),它确定是否 truthy 或 falsey ,但不是(object).==(true)
是返回true还是false