生成::Array的可链接子类



我正试图用可链接的方法创建一个类似Array的类,但我似乎被搞砸了,因为Ruby的Array方法调用:Array.new而不是self.class.new:

class MyArray < Array; end
x = MyArray.new
y = MyArray.new
(x+y).class     # Array, expected MyArray!

我知道我可以遍历并重新实现所有调用其构造函数的Array方法,但这似乎真的是假的。

有趣的是,Set确实"正确"工作:

class MySet < Set; end
x = MySet.new([1,2,3])
y = MySet.new([4,5,6])
(x+y).class     # MySet -- yeah!

我错过了什么?有没有Ruby习惯用法可以用这种方式对Array进行子类化?谢谢

+方法的底层实现在ArraySet之间有所不同。我们可以阅读源代码来找到根本原因:

对于Array,它使用一个新的变量来存储生成的数组:

rb_ary_plus(VALUE x, VALUE y)
{
    VALUE z; 
    long len, xlen, ylen;
    ......
    return z;
}

而对于Set+是:|的别名;它使用dup,它生成原始Set对象的浅拷贝,它不生成新的Set对象来存储结果。

def |(enum)
  dup.merge(enum)
end

是的,我也发现,在stdlib中,类似这样的东西的实现有点不一致。对不起,我不认为有任何简单的神奇答案。并没有真正的ruby习惯用法,ruby并不是真的希望你这么做,有些人发帖主张永远不要对Array或Hash进行子类化。http://words.steveklabnik.com/beware-subclassing-ruby-core-classes

最新更新