Копирование / наследование класса Ruby Matrix (core / std lib) - PullRequest
3 голосов
/ 20 мая 2011

Я попытался расширить существующий класс Singleton в Ruby, например, класс Matrix.

Моим первым быстрым и грязным решением было использование обезьяньего патча (вновь открыть класс и расширить его функциональность).

Но я думаю, что исправление обезьян вообще не очень хорошо, особенно если кто-то пытается переписать базовые методы базовых классов, такие как String, Integer, ...

Следующим шагом было выяснить, как мне получить настоящую печатную копию класса Matrix с новым именем (например, MatrixExt), который ведет себя как отдельный синглтон.

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 работают по-разному?)

Мое текущее решение - иметь модуль с расширением и затем явно использовать .extend после инициализации, например:

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

Пока все нормально, но мой вопрос:

Есть ли другое решение и - когда да - как это сделать?

(Нет, копировать matrix.rb, конечно, не очень хорошо;; o)

Что я делаю неправильно или где я думаю неправильно?

Заранее спасибо за любое решение и / или пищу для размышлений!

Ответы [ 2 ]

2 голосов
/ 11 сентября 2011

Это ошибка.

Я создал проблему на redmine.ruby-lang.org , которая рекомендуется сделать, чтобы исправить это.

Я исправил библиотеку, но, боюсь, она не будет доступна до Ruby 1.9.4.

1 голос
/ 20 мая 2011

Если вы посмотрите, как реализован Matrix, вы заметите, что все методы, такие как scalar, diagonal и т. Д., Вызывают приватный метод new, который всегда будет возвращать новый объект Matrix (вы не переопределяете методы, поэтому Ruby рассмотрит реализацию суперкласса, где неявный получатель new равен self, а именно класс Matrix).

Полагаю, вам лучше всего обернуть все ваши патчи в модуль и патч обезьяны Matrix.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...