Технически, @ndn является правильным, его можно вызвать после оценки класса. Однако похоже, что вы хотите проверить, что метод configure был вызван в какой-то момент в определении тела класса (это также позволит включить любые модули, чтобы завершить оценку, поэтому, если в модуль включены вызовы configure метод, это тоже хорошо).
Ближайшим решение, которое я придумал, чтобы решить эту ситуацию, можно найти здесь:
https://github.com/jasonayre/trax_core/blob/master/lib/trax/core/abstract_methods.rb
Приведенный выше код является абстрактным реализация методов рубина, которые технически не то, что вы спрашивая (вы говорите о вызове метода, абстрактные методы касаются проверки того, что подкласс определил его), но тот же трюк, который я использовал там, может быть применен.
В принципе, я использую библиотеку точек трассировки ruby, чтобы посмотреть, как будет удаляться конец определения класса, после чего он запускает событие, я проверяю, был ли этот метод определен, и выдайте ошибку, если нет. Поэтому, пока вы вызываете configure из WITHIN ваших классов, подобное решение может сработать для вас. Нечто подобное (не проверено):
module MustConfigure
extend ::ActiveSupport::Concern
module ClassMethods
def inherited(subklass)
super(subklass)
subklass.class_attribute :_configured_was_called
subklass._configured_was_called = false
trace = ::TracePoint.new(:end) do |tracepoint|
if tracepoint.self == subklass #modules also trace end we only care about the class end
trace.disable
raise NotImplementedError.new("Must call configure") unless subklass._configured_was_called
end
end
trace.enable
subklass
end
def configure(&block)
self._configured_was_called = true
#do your thing
end
end
end
class A
include MustConfigure
end
class B < A
configure do
#dowhatever
end
end
class C < B
#will blow up here
end
Или, вы можете попробовать использовать модуль InheritanceHooks из моей библиотеки и пропустить ручная обработка Точки трассировки:
class BaseClass
include::Trax::Core::InheritanceHooks
after_inherited do
raise NotImplementedError unless self._configure_was_called
end
end
Обратите внимания, хотя я использую этот шаблон в производстве на данный момент, и все отлично работает на MRI, поскольку tracepoint - это библиотека, созданная для отладки, при использовании jruby существуют некоторые ограничения. (прямо сейчас он ломается, если вы не передаете флаг отладки jruby). Я снова открыл проблему, пытаясь получить добавленную точку трассировки без необходимости явно отлаживать отладку.
https://github.com/jruby/jruby/issues/3096
Когда следует исключать исключение? Когда процесс завершается? Как вы можете знать, что в будущем это не будет называться? – ndn
Исключение должно быть выбрано, когда был определен класс B. Но у вас есть точка с * Как вы можете знать, что в будущем это не будет называться? * – 23tux
Класс может быть вновь открыт.Модуль может быть включен после определения класса. – ndn