扩展Core类比较方法的最佳方法

时间:2013-07-16 03:48:35

标签: ruby coding-style gem override conventions

对于几个预期的场景,我希望我的班级为complete,包括对象比较。我的班级是Hash - 就像它有一个方法to_hash,我的许多课程完成方法都是基于这个方法的。例如:

class Hashlike
  def == other
    if other.respond_to?(:to_hash)
      to_hash == other.to_hash
    end
  end
end

覆盖Hash#==只是为了在消息的超链中注入相似性​​似乎有点过分了:

class Hash
  def == other
    # Flip the comparison
    other.is_a?(Hashlike) ? other == self : super
  end
end

对于完全不相关的问题,这将最终出现在堆栈跟踪中。这感觉很有侵略性。

是否有首选或较少侵入性的方式让Hash了解我的Hashlike是否有资格进行比较?通常,是否存在扩展核心对象(HashArray)以接收核心接口消息(==nil?<==>)和知道自定义类而不会在他们的超级链上留下指纹吗?

更新

我遇到的唯一优化是使覆盖调用超级首先,希望不会因为早期条件分支而阻塞可能使用频繁的方法:

class Hash
  def == other
    # Lazily delay the comparison
    super or (other == self if other.is_a?(Hashlike))
  end
end

一些仔细的基准测试(大约10亿次比较)表明,如果在接收到的对象上定义了to_hash,那么使用任一种方法都会像ruby默认的那样反转比较,如下面的答案中所述

1 个答案:

答案 0 :(得分:1)

哈希已经这样做了。如果某个对象响应to_hash,则Hash#==应该执行other == self以允许此类内容。