为什么';t排序还是太空船(飞碟)操作员(<;=>;)处理Ruby中的布尔值?

为什么';t排序还是太空船(飞碟)操作员(<;=>;)处理Ruby中的布尔值?,ruby,spaceship-operator,Ruby,Spaceship Operator,在“”中,我发现飞碟对布尔人不起作用 考虑: Ruby 1.8.7: [true, false].sort # => undefined method `<=>' for true:TrueClass (NoMethodError) true <=> false # => undefined method `<=>' for true:TrueClass (NoMethodError) [true,false].sort#=>true的未

在“”中,我发现飞碟对布尔人不起作用

考虑:

Ruby 1.8.7:

[true, false].sort # => undefined method `<=>' for true:TrueClass (NoMethodError)
true <=> false     # => undefined method `<=>' for true:TrueClass (NoMethodError)
[true,false].sort#=>true的未定义方法`:TrueClass(NoMethodError)
true-false#=>未定义的true方法“`”:TrueClass(NoMethodError)
Ruby 1.9.3:

[true, false].sort # => comparison of TrueClass with false failed (ArgumentError)
true <=> false     # => nil
true <=> true      # => 0
false <=> true     # => nil
[true,false]。排序#=>将TrueClass与false进行比较失败(ArgumentError)
真假#=>零
真真#=>0
假真#=>零
这可能与没有标准排序顺序的真与假有关,因为哪一个先出现?但是,对我来说,这听起来很弱


这是排序中的一个错误吗?

所谓的飞碟需要所有的比较运算符(
==
)工作(不是技术上的,尽管理论上肯定是这样)
true
false
不小于或大于彼此。这同样适用于
nil
。对于实际的解决方法,您可以“强制转换”为整数(0表示false,1表示true)。比如:

[true, false, true].sort_by{|e| e ? 1 : 0}
布尔值没有自然顺序。
Ruby语言设计师可能认为,发明布尔运算的顺序对开发人员来说是一个惊喜,因此他们故意忽略了比较运算符。

布尔运算没有自然的顺序。与C不同,false不亚于true,它们只是等价且同样有效的状态。但是,可以使用块以任何方式配置排序,例如:

ary = [true, false, false, true]
ary.sort {|a,b|  a == b ? 0 : a ? 1 : -1 }

# => [false, false, true, true]
颠倒顺序也很简单:

ary.sort {|a,b|  a == b ? 0 : a ? -1 : 1 }

# => [true, true, false, false]

不要把你的误解归咎于Ruby的错误(bug)。那么也许问题应该是,为什么要费心为布尔人实现“”。这有点奇怪
应始终返回
0
-1
、或
1
,或未定义。返回
nil
违反了预期。我同意。@sawa来自:“如果另一个对象不可比较,那么操作员应该返回nil。”@sawa:
的返回值是
-1
0
1
nil
的小于、等于、大于和不可比较值。这是
的标准协议,我看不出Boolean的实现如何违反该协议
true
等于
true
,但它不能与
false
相比。我理解“true和false不小于或大于彼此”——我在问Ruby为什么会这样设计?使用一个简单的
[true,false].sort
@products.sort_by(&:on_sale?)
对布尔数组进行排序似乎比使用一种通常很有弹性的语言进行突然故障排序有用得多。作为一个设计问题,很可能是因为人们无法真正猜测开发人员的意图。比较
true>false
时,您希望看到什么值?在某些语言中,false等于0,而true可能是1或-1。这是一个武断的决定,设计者可能认为应该由开发者做出。顺便说一句,PHP试图对此做些什么,这可能会让它在这个过程中变得更加混乱……飞碟并不需要所有的比较操作符来工作。相反,定义了
并包含了,所有的比较方法都是“免费”定义的。@steenslag:技术上正确,但想法保持不变。
的实现应该代表比较运算符的功能。更新以澄清这一点-感谢您指出这一点。@AlexChaffee:为什么您希望Ruby能够对无法排序的内容进行排序?是的。除了实现了
,即使
未实现。在Ruby 1.9中,
似乎是(“如果obj==other,则返回0,否则返回nil”),而正是这个实现混淆了
排序
的真假。@AlexChaffee:啊,是的,我明白了,这意味着布尔人有一个坏掉的太空船操作符。瘸子@maerics:布尔人的
实现完全符合
协议。它是以什么方式“被破坏的”@JörgWMittag:hmm,我假设
操作符用于比较ala排序(返回值-1,0,1),但在阅读更多文档(例如数字)后,似乎情况并非如此。我所说的“半途而废”是指让我感到困惑,因为它违反了我认为是宇宙飞船运营商实施比较的惯例。这只是一个错误的决定。布尔代数基本上是一个格,上下(真和假)绝对是可比的。