Итак, я пересматривал свой код в своем маленьком приложении Rails, пытаясь удалить дублирование, и в целом облегчить жизнь (как мне нравится легкая жизнь). Часть этого рефакторинга заключалась в том, чтобы переместить код, общий для двух моих моделей, в модуль, который я могу включить там, где он мне нужен.Ruby mixins и вызовы супер методов
До сих пор так хорошо. Похоже, что это сработает, но я только что попал в проблему, и я не уверен, как обойти. Модуль (который я назвал sendable), будет просто кодом, который обрабатывает факсы, электронную почту или печать PDF документа. Так, например, у меня есть заказ на поставку, и у меня есть внутренние заказы на продажу (по образцу сокращенно ISO).
Проблема Я поражен, что я хочу некоторые переменные инициализируются (инициализированы для людей, которые не разъясняются правильно: P) после загрузки объекта, поэтому я использую after_initialize крючок. Нет проблем ... пока я не начну добавлять еще несколько миксинов.
У меня есть проблема, что я могу иметь after_initialize
в одном из моего Mixins, так что мне нужно, чтобы включить супер вызова на старте, чтобы убедиться в других подмешать after_initialize
звонков дозвонились , Это здорово, пока я не позвоню супер, и я получаю сообщение об ошибке, потому что супер не звонит.
Вот небольшой пример, в случае, если я не путая достаточно:
class Iso < ActiveRecord::Base
include Shared::TracksSerialNumberExtension
include Shared::OrderLines
extend Shared::Filtered
include Sendable::Model
validates_presence_of :customer
validates_associated :lines
owned_by :customer
order_lines :despatched # Mixin
tracks_serial_numbers :items # Mixin
sendable :customer # Mixin
attr_accessor :address
def initialize(params = nil)
super
self.created_at ||= Time.now.to_date
end
end
Таким образом, если каждый из Mixins есть вызов after_initialize с супер вызова, как я могу остановить что последний супер позвонить с поднятием ошибки? Как я могу проверить, существует ли супер-метод до того, как я его назову?
Downvoted, потому что это не является общим решением. Дело в том, что вы не знаете, существует ли супер, так что monkeypatching ActiveRecord :: Base # after_initialize будет существовать, вы создадите точку, в которой ваш код сломается, если/когда ActiveRecord добавляет Base # after_initialize или изменяется его arity ; это далеко не так условно назвать это, если оно определено. – yaauie 2012-04-03 00:15:10
@yaauie - конечно, я мог бы поставить `raise 'oh no' if methods.include? (: After_initialize)` перед monkeypatch, но это сделало бы труднее понять этот пример ... Так легко попасть подробно описывая все случаи кросс, что настоящий урок здесь (просто исправить базовый метод) будет потерян в шуме. – 2012-04-11 00:29:33