在Cooper的书 Beginning Ruby ,第166页中有一个我无法再现的例子。
class Song
include Comparable
attr_accessor :length
def <=>(other)
@length <=> other.length
end
def initialize(song_name, length)
@song_name = song_name
@length = length
end
end
a = Song.new('Rock around the clock', 143)
b = Song.new('Bohemian Rhapsody', 544)
c = Song.new('Minute Waltz', 60)
a.between?(b, c)
在书中,它说结果应该是=> true
,而我正在=> false
。
我接着把它分解为......
puts 143.between?(544, 60) # => false
puts 143.between?(60, 544) # => true
根据ruby-doc.org,它应该写成between?(min,max)
- 这让我相信
(max,min)
这是什么?
答案 0 :(得分:4)
经过快速调查后,看起来这只是书中的一个错误(如果你正确引用它)。
我发现这本书是pdf here。遗憾的是,缺少第166页。但是,在第5页,它说:
在“Ruby on Windows”部分中,您将看到可以为Windows下载的不同版本Ruby的一些链接。理想情况下,您希望在名为“一键安装程序”的列表中最高的链接下载该文件。 在撰写本文时,此版本为1.8.5。
检查CRuby's 1.8.5 Comparable
implementation,您可以清楚地看到between?
的工作方式与今天的方式相同。
答案 1 :(得分:2)
我只是想告诉你这件事。这是between?
方法的C源:
static VALUE
cmp_between(VALUE x, VALUE min, VALUE max)
{
if (RTEST(cmp_lt(x, min))) return Qfalse;
if (RTEST(cmp_gt(x, max))) return Qfalse;
return Qtrue;
}
虽然我没有查看每个版本,但我相信这个方法自Ruby 1.8.7以来一直保持不变。
普通英语中的cmp_lt
和cmp_gt
是“比较小于”和“比较大于”。
正如您所看到的,如果值x
(在您的情况下是a
对象长度为144)小于min },则该方法将返回false strong>,这将是b
的长度544.自144&lt; 1&gt; 544,你得到了正确的答案,看来这本书确实存在错误。
我似乎无法确定之前是否曾报告此错误,因此如果您有意愿,请与作者联系并让他知道。
答案 2 :(得分:2)
上面的一些评论已经涵盖了这一点,但作为本书的作者,我想澄清一下,本书的2009版(第2版)已经纠正了这个问题。原始海报已更新,他们正在阅读2007版: - )
然而,作为该问题的明确答案,是的,本书的第一版出错了。