我正试图用可链接的方法创建一个类似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进行子类化?谢谢
+
方法的底层实现在Array
和Set
之间有所不同。我们可以阅读源代码来找到根本原因:
对于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