#之间? Cooper的错误或异常*开始Ruby *

时间:2015-11-27 17:17:05

标签: ruby

在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) - 这让我相信

  • a)这本书有错误
  • b)在早期版本的Ruby中,介于两者之间? 更灵活,允许(max,min)
  • c)这个例子在某种程度上是异常的,我是 遗失了什么

这是什么?

3 个答案:

答案 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_ltcmp_gt是“比较小于”和“比较大于”。

正如您所看到的,如果值x(在您的情况下是a对象长度为144)小于min ,这将是b的长度544.自144&lt; 1&gt; 544,你得到了正确的答案,看来这本书确实存在错误。

我似乎无法确定之前是否曾报告此错误,因此如果您有意愿,请与作者联系并让他知道。

答案 2 :(得分:2)

上面的一些评论已经涵盖了这一点,但作为本书的作者,我想澄清一下,本书的2009版(第2版)已经纠正了这个问题。原始海报已更新,他们正在阅读2007版: - )

然而,作为该问题的明确答案,是的,本书的第一版出错了。