开发者

Copy/Inheritance of Ruby Matrix class (core/std lib)

开发者 https://www.devze.com 2023-03-07 07:21 出处:网络
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).

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!


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消