Ruby Matrix类的复制/继承(core / std lib)

时间:2011-05-19 21:07:47

标签: ruby inheritance matrix singleton

我尝试在Ruby中扩展现有的Singleton类,例如Matrix类。

我的第一个 quick& dirty 解决方案是一个猴子补丁(重新打开类并扩展功能)。

但我认为,猴子修补一般不好,特别是如果有人试图覆盖核心类的基本方法,如String,Integer,...

下一步是找出如何使用新名称(如MatrixExt)获取Matrix类的真实硬拷贝,该名称表现为独立的单例。

MatrixExt = Matrix

没有工作,因为它导致:

MatrixExt.scalar(2,0)
=> Matrix[[0, 0], [0, 0]]

所以我只为同一个单身人士获得多个名字。不,我想要的。

clonedup方法的结果相同。

类继承也不起作用:

class MatrixExt < Matrix
  # patches ...
end

MatrixExt.scalar(2,0)
=> Matrix[[0, 0], [0, 0]]

这是最令人困惑的部分,因为在自定义类中,可以获得一个继承的类。 (那么,为什么core / std lib类的工作方式不同?)

我目前的解决方案是使用扩展模块,然后在初始化后明确使用.extend,例如:

m = Matrix.scalar(2,0).extend(MatrixExtModule)

现在没关系,但我的问题是:

是否有其他解决方案 - 是 - 如何做到?

(不,复制matrix.rb当然不是一个好方法。; o)

我做错了什么或我认为错误的方式?

提前感谢任何解决方案和/或食物的想法!

2 个答案:

答案 0 :(得分:2)

这是一个错误。

我已经创建了一个issue on redmine.ruby-lang.org,这是修复这些问题的建议。

我修复了库,但我担心它会在Ruby 1.9.4之前无法使用。

答案 1 :(得分:1)

如果您查看Matrix的实施方式,您会发现scalardiagonal等所有方法都会调用私有new方法,总是返回一个新的Matrix对象(你不会覆盖这些方法,所以Ruby会查看超类实现,其中new的隐式接收者是self,即{{ 1}}类)。

我猜你最好的办法就是将所有补丁包装在一个模块中,然后以Matrix方式将补丁包裹起来。