Как я могу расширить класс из драгоценного камня?
Я написал драгоценный камень с некоторой базовой логикой, которой я хотел поделиться. Я публикую это, установите это, используйте это.
Есть дополнительные функции, которые, на мой взгляд, зависят от конкретного случая моего проекта. Я хочу добавить дополнительные методы, используя одно и то же имя класса, потому что оно знакомо, и мне все легко отслеживать мысленно.
Как я могу установить гем, а затем добавить методы без конфликтов? В прошлом я переписывал методы, определенные в гемах (в частности, методы Devise), но никогда не сталкивался с необходимостью расширения самого класса.
1 ответ
Вы просто открываете класс и добавляете методы. Если вы знаете имя класса и его местонахождение в иерархии модулей, вы просто создаете другой файл, который определяет тот же класс, и начинаете добавлять методы. Поскольку это то же имя класса, методы будут добавлены к другому классу.
Вероятно, это похоже на то, что вы сделали с Devise.
Так что, если у меня есть класс Bar
в драгоценном камне, и это внутри модуля под названием Foo
# in the gem
module Foo
class Bar
def foobar
'foobar!'
end
end
end
Чтобы добавить метод с именем baz
к этому классу, без изменения исходного кода gem, затем в вашем приложении просто создайте новый файл, снова объявите класс внутри его модуля и начните добавлять вещи.
# in some other file in your app
module Foo
class Bar
def baz
'foobar baz!'
end
end
end
> f = Bar.new
> f.foobar
=> 'foobar!'
> f.baz
=> 'foobar baz!'
Поскольку в модуле может быть только одна копия класса с заданным именем, простое объявление класса снова добавляет функциональность к существующему классу.
Если вы хотите вместо этого дать новый класс baz
метод без изменения функциональности всех Bar
экземпляры объектов в вашем приложении, а затем расширить Bar
вместо. Это будет иметь эффект, что ваш новый класс будет иметь все Bar
функциональность, плюс новая функциональность, без изменения функциональности Bar
случаи, которые вы можете использовать в другом месте в вашем приложении.
class NewClass < Foo::Bar
def baz
'foobar baz!'
end
end
> nc = NewClass.new
> nc.foobar
=> 'foobar!'
> nc.baz
=> 'foobar baz!'