Ruby(Rails 4.0.2):( 1 == true)=>假?

时间:2014-10-24 20:01:36

标签: ruby sql-server ruby-on-rails-4 boolean

我的理解是,在Ruby编程语言中,只有nilfalse被认为是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}}。

我很惊讶在我遇到这样的问题之前花了几年时间!

4 个答案:

答案 0 :(得分:3)

  

我的理解是,在Ruby编程语言中,只有nil和false被认为是假的,而其他一切都被认为是真的

这是事实。

然而,

  

&#34;因此,1 == true应该返回true。&#34;

是假的。

说明:在Ruby中,除false / nil之外的所有内容都被认为是真的。 然而在测试相等性时,例如x == true您实际上没有测试&#34;此值是否为真&#34;但是&#34;这个值等于为真&#34;。

当然1不等于true1是一个数字,true是一个布尔值。你可以在&#34; Ruby Equality And Object Comparison&#34;

阅读一篇关于Ruby中的平等的非常好的博客文章。

如果你真的,真的想以这种方式测试它,你需要将像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)

就逻辑谓词而言,除nilfalse之外的每个对象都是 TRUTHY 。什么基本上意味着将执行对应我们的谓词(条件)的语句。

虽然nilfalse FALSEY 谓词。

在实践中,它意味着:

if predicate
  statement_a
else
  statement_b
end

除了nilfalse 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

现在当你说除了nilfalse之外的所有内容都被认为是真的,正确的说法是在Ruby中只有falsenil falsey ,其他一切都是 truthy 。因此,当Ruby必须决定某个值或对象计为计算为真时(例如在if语句中:if ('test')),它确定是否 truthy falsey ,但不是(object).==(true)是返回true还是false