0

我有一些使用受保护级别 attr_readers 能够实现 == 方法的 Ruby 代码,以便我们可以断言一些结果日历等于预期的日历),但是除了测试中的断言之外,任何代码都不需要这些受保护的访问器代码。

我的一些代码如下所示:

class Calendar    
  def initialize(date_times)
    @date_times = date_times
  end

  def next_date_time
    @date_times.find { |time| time - DateTime.now > 0 }
  end

  def ==(other)
    @date_times == other.date_times
  end

  protected

  attr_reader :date_times
end

如何避免需要受保护的 attr_readers?实际上,理想情况下,如果我也可以消除对 the 的需求,def==(......那就太好了,因为它也只在测试中需要!

一切顺利,亚历克斯

第一次尝试:

module Kernel
  def subclass_with_equals(class_symbol)
    clazz = Kernel.const_get(class_symbol.to_s)
    Kernel.subclass_with_default_equals(clazz)
  end

  private

  def self.subclass_with_default_equals(base_class)
    sub_class = Class.new(base_class)
    sub_class.class_eval do
      def ==(other)
        instance_variables.all? { |v| self.instance_variable_get(v) == other.instance_variable_get(v) } and other.instance_of? self.class
      end
    end
    sub_class
  end
end

在我的规范文件的顶部,我可以添加这一行来为我的类添加一个默认的 == 方法:

Calendar = sub_class_with_equals :Calendar

这使我能够从日历类中删除五六行!

4

1 回答 1

2

您可以从测试代码中对类进行猴子补丁,此时您最好摆脱#protected() 调用。

更好的方法是从测试代码中创建一个具有访问器和 == 方法的 Calendar 子类。

于 2010-10-24T22:07:24.790 回答