Ответ 1
У классов нет имен в Ruby. Это просто объекты, назначенные переменным, как и любой другой объект. Если вы хотите обратиться к классу с помощью другой переменной, назначьте его другой переменной:
Foo = String
Я разрабатываю новое приложение Rails на основе аналогичного существующего. В моем старом приложении у меня класс Coupon, который очень похож на Ticket в моем новом приложении. Я хочу повторно использовать весь код в купоне, но с новым именем класса.
Поскольку рефакторинг громоздкий в Rails, мне интересно, есть ли способ создать псевдоним для класса в Ruby (аналогично псевдониму для атрибутов и методов).
У классов нет имен в Ruby. Это просто объекты, назначенные переменным, как и любой другой объект. Если вы хотите обратиться к классу с помощью другой переменной, назначьте его другой переменной:
Foo = String
в файле coupon.rb:
class Coupon
#...
end
# add this line of code to make alias for class names
# option1. if you haven't defined a "Ticket" class:
Ticket = Coupon
# option2. if Ticket has been defined, you have to redefine it:
Object.send :remove_const, "Ticket"
const_set "Ticket", Coupon
"Любая ссылка, которая начинается с буквы верхнего регистра, включая имена классов и модулей, является константой" - < < метапрограммирование рубина → , стр. 38, постоянный раздел
Любой, кто приходит сюда, ищет, как псевдоним класса модели rails иметь новое имя:
Мне удалось просто выполнить Foo = Bar
, но мне пришлось поместить Foo
в собственный файл модели, чтобы я не получил Uninitialized Constant Error. например.
# models/foo.rb
Foo = Bar
Кроме того, вы можете найти странность, пытаясь использовать псевдоним в таких ассоциациях, как has_many
, has_one
и т.д. Я обнаружил, что вы обычно можете обойти их, используя корневое пространство имен (или соответствующее пространство имен в зависимости от того, как ваши модели структурированный), чтобы убедиться, что Rails пытается автозагрузить правильную константу:
has_many :foo, class_name: '::Foo'
Я согласен с warhog, более или менее - но я бы подписал билет с вашего класса купона - таким образом, если вам нужно выполнить какое-либо перехват данных, вы можете поместить код в свой класс билетов
Вы должны быть осторожны с этим, потому что если ваш класс подвергается любому изменению состояния (добавленные функции, измененные константы, переменные класса и т.д.), состояние вашего класса в при псевдониме был создан не будет отражать обновленные изменения в вашем классе.
Чтобы избежать туннеля с запястью, не жертвуя удобочитаемостью, вы можете хранить лямбда в своем объекте псевдонима, а не в действительном классе. Конечно, лямбда содержит класс, но это гарантирует, что ваш псевдоним вызовет последнюю версию вашего класса.
Я помещаю это в мой инициализатор рельсов supermanpatches.rb
(внутри config/initializers/
) & Dagger;
LAP = lambda { LosAngelesParcel }
Теперь вы можете вызвать это, используя LAP[]
, и будет загружена свежеиспеченная версия вашего класса. (Позволяет создавать экземпляры, например, l = LAP[].new
)
& Dagger; запускается один раз, когда рельсы загружаются, а затем распространяются через ваше приложение, вызывается везде, как глобальная переменная, но "только для чтения", так сказать.