Ruby Matrix 类的复制/继承(核心/标准库)

发布于 2024-11-08 20:54:01 字数 1181 浏览 1 评论 0原文

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

我的第一个快速&肮脏解决方案是猴子补丁(重新开放类并扩展功能)。

但我认为,猴子修补一般来说并不好,特别是如果有人试图覆盖核心类的基本方法,如 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)

我做错了什么或者我在哪里思考错误的方式?

提前感谢任何解决方案和/或思考!

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流心雨 2024-11-15 20:54:01

这是一个错误。

我在 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.

牵你的手,一向走下去 2024-11-15 20:54:01

如果您查看 Matrix 的实现方式,您会发现所有方法(例如 scalardiagonal 等)都会调用私有 new 方法,它总是返回一个新的 Matrix 对象(您不会重写这些方法,因此 Ruby 会查看超类实现,其中 new 的隐式接收者self,即矩阵类)。

我想你最好的选择是将所有补丁包装在一个模块中,并以这种方式猴子补丁Matrix

If you look at how Matrix is implemented, you'll notice that all the methods like scalar, diagonal etc. call the private new method, which will always return a new Matrix object (you don't override the methods, so Ruby will go look at the superclass implementation, where the implicit receiver of new is self, viz the Matrix class).

I guess your best bet is to wrap all your patches in a module and monkey patch Matrix that way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文