Подтвердить что ты не робот

Атрибут класса в Ruby

Я разрабатываю новое приложение Rails на основе аналогичного существующего. В моем старом приложении у меня класс Coupon, который очень похож на Ticket в моем новом приложении. Я хочу повторно использовать весь код в купоне, но с новым именем класса.

Поскольку рефакторинг громоздкий в Rails, мне интересно, есть ли способ создать псевдоним для класса в Ruby (аналогично псевдониму для атрибутов и методов).

4b9b3361

Ответ 1

У классов нет имен в Ruby. Это просто объекты, назначенные переменным, как и любой другой объект. Если вы хотите обратиться к классу с помощью другой переменной, назначьте его другой переменной:

Foo = String

Ответ 2

в файле 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, постоянный раздел

Ответ 3

Любой, кто приходит сюда, ищет, как псевдоним класса модели rails иметь новое имя:

Мне удалось просто выполнить Foo = Bar, но мне пришлось поместить Foo в собственный файл модели, чтобы я не получил Uninitialized Constant Error. например.

# models/foo.rb
Foo = Bar

Кроме того, вы можете найти странность, пытаясь использовать псевдоним в таких ассоциациях, как has_many, has_one и т.д. Я обнаружил, что вы обычно можете обойти их, используя корневое пространство имен (или соответствующее пространство имен в зависимости от того, как ваши модели структурированный), чтобы убедиться, что Rails пытается автозагрузить правильную константу:

has_many :foo, class_name: '::Foo'

Ответ 4

Я согласен с warhog, более или менее - но я бы подписал билет с вашего класса купона - таким образом, если вам нужно выполнить какое-либо перехват данных, вы можете поместить код в свой класс билетов

Ответ 5

Вы должны быть осторожны с этим, потому что если ваш класс подвергается любому изменению состояния (добавленные функции, измененные константы, переменные класса и т.д.), состояние вашего класса в при псевдониме был создан не будет отражать обновленные изменения в вашем классе.

Чтобы избежать туннеля с запястью, не жертвуя удобочитаемостью, вы можете хранить лямбда в своем объекте псевдонима, а не в действительном классе. Конечно, лямбда содержит класс, но это гарантирует, что ваш псевдоним вызовет последнюю версию вашего класса.

Я помещаю это в мой инициализатор рельсов supermanpatches.rb (внутри config/initializers/) & Dagger;

LAP = lambda { LosAngelesParcel }

Теперь вы можете вызвать это, используя LAP[], и будет загружена свежеиспеченная версия вашего класса. (Позволяет создавать экземпляры, например, l = LAP[].new)

& Dagger; запускается один раз, когда рельсы загружаются, а затем распространяются через ваше приложение, вызывается везде, как глобальная переменная, но "только для чтения", так сказать.