Я столкнулся с проблемой, что сторонняя библиотека должна работать с классом так, как если бы он был завершен. После некоторого чтения я понимаю мотивацию этого механизма, но я действительно не знаю, как он работает.
Пример:
(make-instance 'expression :op '+ :left 'nan :right 'nan)
(defmethod normalize-expression ((this expression))
(optima:match this
((optima::or (expression :left 'nan) (expression :right 'nan)) 'nan)
((expression :op op :left x :right y) (funcall op x y))))
Если я не добавлю первую строку, функция не скомпилируется, что даст мне эту ошибку:
; caught ERROR:
; (during macroexpansion of (SB-PCL::%DEFMETHOD-EXPANDER NORMALIZE-EXPRESSION ...))
; SB-MOP:CLASS-SLOTS called on #<STANDARD-CLASS EXPRESSION>, which is not yet finalized.
; See also:
; AMOP, Generic Function SB-MOP:CLASS-SLOTS
optima
— это библиотека сопоставления с образцом, (expression :op op ...)
— сопоставление экземпляров класса expression
с заданным образцом. Я не знаю подробностей, но похоже, что ему нужно знать, какие методы доступа определены для этого класса, и похоже, что эта информация недоступна, пока она не будет завершена. Итак, есть ли способ обойти проблему финализации?
Класс не будет продлен (по крайней мере, в этом проекте и не планируется). Создать фиктивный экземпляр не так уж больно... это просто уродливое решение, поэтому я надеялся найти лучшее. Также, возможно, я бы получил больше информации о доработке, что тоже хорошо :)