Я попытался расширить существующий класс 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)
Что я делаю неправильно или где я думаю неправильно?
Заранее спасибо за любое решение и / или пищу для размышлений!