Ruby Matrix 类的复制/继承(核心/标准库)
我尝试扩展 Ruby 中现有的 Singleton 类,例如 Matrix 类。
我的第一个快速&肮脏解决方案是猴子补丁(重新开放类并扩展功能)。
但我认为,猴子修补一般来说并不好,特别是如果有人试图覆盖核心类的基本方法,如 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)
我做错了什么或者我在哪里思考错误的方式?
提前感谢任何解决方案和/或思考!
I tried to extend an existing Singleton class in Ruby, as an example the Matrix class.
My first quick&dirty solution was a monkey patch (reopen class and extend with functionality).
But I think, monkey patching in general isn't good, especially if someone tries to overwrite basic methods of core classes like in String, Integer, ...
Next step was to find out, how I can get a real hard copy of the Matrix class with a new name (like MatrixExt) which behaves as a standalone singleton.
MatrixExt = Matrix
didn't the job, as it results in:
MatrixExt.scalar(2,0)
=> Matrix[[0, 0], [0, 0]]
So I only get multiple names for same singleton. Not, what I want.
Same result with the clone
and the dup
methods.
Also class inheritance won't work:
class MatrixExt < Matrix
# patches ...
end
MatrixExt.scalar(2,0)
=> Matrix[[0, 0], [0, 0]]
And that was the most confusing part, because in self defined classes it is possible to get an inherited class. (So, why the core/std lib classes work different?)
My current solution is to have a module with extension and then explicitly use .extend
after initializing, like:
m = Matrix.scalar(2,0).extend(MatrixExtModule)
That is okay for now, but my question is:
IS there another solution and -when yes- how to do it?
(No, copying the matrix.rb is not a good way, of course. ;o)
What I do wrong or where I think in a wrong way?
Thanks in advance for any solution and/or food for thoughts!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个错误。
我在 redmine.ruby-lang.org 上创建了一个问题,这是推荐的解决这些问题需要做的事情。
我修复了这个库,但恐怕要到 Ruby 1.9.4 才可用。
This is a bug.
I've created an issue on redmine.ruby-lang.org, which is the recommended thing to do to get these fixed.
I fixed the library, but I'm afraid it won't be available until Ruby 1.9.4.
如果您查看
Matrix
的实现方式,您会发现所有方法(例如scalar
、diagonal
等)都会调用私有new
方法,它总是返回一个新的Matrix
对象(您不会重写这些方法,因此 Ruby 会查看超类实现,其中new 的隐式接收者
是self
,即矩阵
类)。我想你最好的选择是将所有补丁包装在一个模块中,并以这种方式猴子补丁
Matrix
。If you look at how
Matrix
is implemented, you'll notice that all the methods likescalar
,diagonal
etc. call the privatenew
method, which will always return a newMatrix
object (you don't override the methods, so Ruby will go look at the superclass implementation, where the implicit receiver ofnew
isself
, viz theMatrix
class).I guess your best bet is to wrap all your patches in a module and monkey patch
Matrix
that way.