在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)
在书中,它说当我得到=> false
时,结果应该是=> true
。
我接着把它分解成…
puts 143.between?(544, 60) # => false
puts 143.between?(60, 544) # => true
根据ruby-doc.org的说法,它应该写成between?(min,max)
——这让我相信
- a) 这本书有个错误
- b) 在早期版本的Ruby中,介于?更灵活并允许
(max,min)
- c) 这个例子有点反常,我错过了什么
是哪一个?
经过快速调查,这似乎只是书中的一个错误(如果引用正确的话)。
我在这里找到了这本pdf格式的书。遗憾的是,第166页不见了。然而,在第5页上,它说:
在"Ruby on Windows"部分,您将看到一些可以为Windows下载的不同版本Ruby的链接。理想情况下,您希望在被称为"一键安装程序"的列表中最高的链接处下载文件。在撰写本文时,此版本为1.8.5。
检查CRuby的1.8.5 Comparable
实现,您可以清楚地看到between?
的工作方式与今天一样。
上面的一些评论已经涵盖了这一点,但作为这本书的作者,我想澄清的是,这本书2009年版(第2版)已经纠正了这个问题。原始海报已经更新,他们正在阅读2007年版:-)
然而,作为对这个问题的明确回答,是的,这本书的第一版是错误的。
我只是想向您展示一下。这是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
分别是"compare less than"one_answers"compare great than"。
因此,正如您所看到的,如果值x
(在您的情况下是您的a
对象长度144)小于最小值(即b
的长度544),则该方法将返回false。由于144<544,你得到了正确的答案,而且这本书似乎确实有一个错误。
我似乎无法确定这个错误以前是否被报道过,所以如果你有兴趣,最好联系作者并让他知道。