我尝试在Ruby中扩展现有的Singleton类,例如Matrix类。
我的第一个 quick& dirty 解决方案是一个猴子补丁(重新打开类并扩展功能)。
但我认为,猴子修补一般不好,特别是如果有人试图覆盖核心类的基本方法,如String,Integer,...
下一步是找出如何使用新名称(如MatrixExt)获取Matrix类的真实硬拷贝,该名称表现为独立的单例。
MatrixExt = Matrix
没有工作,因为它导致:
MatrixExt.scalar(2,0)
=> Matrix[[0, 0], [0, 0]]
所以我只为同一个单身人士获得多个名字。不,我想要的。
与clone
和dup
方法的结果相同。
类继承也不起作用:
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)
我做错了什么或我认为错误的方式?
提前感谢任何解决方案和/或食物的想法!
答案 0 :(得分:2)
答案 1 :(得分:1)
如果您查看Matrix
的实施方式,您会发现scalar
,diagonal
等所有方法都会调用私有new
方法,总是返回一个新的Matrix
对象(你不会覆盖这些方法,所以Ruby会查看超类实现,其中new
的隐式接收者是self
,即{{ 1}}类)。
我猜你最好的办法就是将所有补丁包装在一个模块中,然后以Matrix
方式将补丁包裹起来。