-2

我不确定如何使以下测试用例通过。我将 source 用于 union (|) 和内部 list.include?(source)

 class Source
  # mongoid object code...
  def hash
    url.hash
  end

  def ==(other)
    eql?(other)
  end

  def eql?(other_source)
    url = self.url and other_source and url == other_source.url
  end
end

测试用例:

  ext1 = Source.new
  ext2 = Source.new(url: "test")

  (ext2.== ext1).should               == false # false
  (ext1.== ext2).should               == false # is returning nil instead of false

我想让最后一个案例返回 false 而不是 nil 但不知道如何让这种情况发生?

4

4 回答 4

1

常见的模式是“双敲”表达式:

!!(url = self.url && other_source && url == other_source.url)

这将强制为trueor的任何值false

(此外,Ruby 风格指南建议使用&&and||代替andand or

于 2013-06-03T02:47:17.543 回答
1

当我运行您的代码并点击该行时

  ext2 = Source.new(url: "test")

我明白ArgumentError: wrong number of arguments(1 for 0)了,所以我不确定这是否可行,但也许你的意思是

  def eql?(other_source)
    url == self.url and other_source and url == other_source.url
  end
于 2013-06-03T02:47:54.850 回答
1

为什么是 url 变量呢?

# if they need to be the same class to be equal
def eql(other_source)
  Source === other_source && other_source.url == self.url
end

# OR, if it just matters that it responds to url
def eql(other_source)
  other_source.respond_to?(:url) && other_source.url == self.url
end

请注意,other_source如果它是真实的并且仍然没有 url 属性,则仅测试真实性不会阻止异常,因此如果您说,您当前的解决方案会引发异常,例如ext1 == true

更不用说在您的示例中,ext1不可能是eql任何东西,因为您要测试的第一件事是self.url. 这是你想要的吗?url如果这是标准,那么至少两个没有 no 的来源不会被认为是相等的吗?

于 2013-06-03T03:01:12.450 回答
0

我不确定您是否忘记粘贴一些代码,但我认为您的意思是这样的:

class Source
  attr_reader :url

  def initialize(params = {})
    @url = params[:url]
  end

  def hash
    @url.hash
  end

  def ==(other)
    eql?(other)
  end

  def eql?(other_source)
    other_source && @url == other_source.url
  end
end

这解决了您的问题,同时修复了其他几个问题:

  1. 您需要一个名为的实例变量url和一个 getter。
  2. 你需要一个initialize方法。

eql?那么只需要确定other_sourceis notnil并比较urls:

ext2.== ext1 # => false
ext1.== ext2 # => false
于 2013-06-03T02:58:28.427 回答