0

如何指定一个类与日期相比较?

class FolderDate

  attr_reader :folder

  def initialize folder
    @folder = folder
  end
end

class AsteriskFolderDate < FolderDate

  include Comparable

  attr_reader :date

  def initialize folder
    super
    @date = get_date
  end

  def <=>(other)
    @date <=> other
  end

  private
    #omitted
end

在 Rails 控制台中...

AsteriskFolderDate.new("20130628") > Date.today-1
 => true
AsteriskFolderDate.new("20130627") > Date.today
 => false 

规格文件...

describe "An instance of", AsteriskFolderDate do
  let(:folder) { DateFolder.new(Date.today).asterisk_folder }

  subject { AsteriskFolderDate.new(folder) }

  #omitted

  it "should compare based on @date" do
    expect( Date.today-1 ).to be < subject
    expect( subject ).to be > Date.today-1
  end
end

测试失败...

Failure/Error: expect( Date.today-1 ).to be < subject
  ArgumentError:
   comparison of Date with AsteriskFolderDate failed

控制台输出让我想认为它正在工作,但测试失败了。我在正确的轨道上,还是测试指出了我在控制台中缺少的缺陷?

4

2 回答 2

1

问题是您比较的顺序。如果您在 Rails 控制台中执行此操作:

Date.today < AsteriskFolderDate.new("20130627")

你会看到同样的错误。只有一个断言会引发错误:

it "should compare based on @date" do
  expect( Date.today-1 ).to be < subject  # Fails
  expect( subject ).to be > Date.today-1  # Works
end

这是因为 AsteriskFolderDate 知道如何将自己与 Date 进行比较,但标准的 ruby​​ Date 对象对 AsteriskFolderDate (这是预期的)一无所知。

如果您希望比较以两种方式工作,则需要以某种方式修改 Date 类。

于 2013-06-29T01:13:02.353 回答
1

您在AsteriskFolderDate类中指定了方法,使其与Date. 因此,以下内容可以正常工作:

AsteriskFolderDate.new(Date.today.strftime("%Y%m%d")) > Date.today-1
#=> true
AsteriskFolderDate.new((Date.today - 1).strftime("%Y%m%d")) > Date.today
#=> false

但是你没有猴子补丁Date使它与你的自定义类相媲美AsteriskFolderDate。并且当您编写消息时,Date.today < AsteriskFolderDate.new("20130627")<发送到 的实例Date,但是Date不知道如何与 进行比较AsteriskFolderDate,因此会引发参数错误Date#<

Date.today-1 < AsteriskFolderDate.new(Date.today.strftime("%Y%m%d"))
# folder_date.rb:23:in `<': comparison of Date with FolderDate failed (ArgumentError)
#        from folder_date.rb:23:in `<main>'
于 2013-06-29T01:14:07.707 回答