When ASDF is being applied for the compilation and loading of a Common Lisp software system, the following method definition will effectively prevent the redefinition errors from being rendered as errors. The warning notice, as emitted, will contain the original redefinition error, as an object within the simple-condition-format-arguments of the warning object. The message printed from the warning notice will likewise print the text of message from the original redefinition error.
This source code snippet is provided with the following footnotes:#+asdf (defmethod asdf:operate :around ((operation asdf:load-op) (component asdf:component) &key &allow-other-keys) (declare (ignore operation component)) (handler-bind ((sb-ext:defconstant-uneql #'(lambda (c) (let ((previous (sb-ext:defconstant-uneql-old-value c)) (new (sb-ext:defconstant-uneql-new-value c))) (cond ((equalp previous new) (warn "Redefining constant: ~A" c) (invoke-restart 'continue)) (t (error c))))))) (call-next-method)))
- This method is defined as an :around method, to avoid collision with primary methods defined onto asdf:operation
- The method is specialized onto the classes, asdf:load-op and asdf:component. The class, asdf:load-op is applied as a specializer, instead of of asdf:operation, in assuming that most of the uninteresting defconstant redefinitions would occur during load-time -- typically, immediately after the same component would have been compiled
- If the previous and new values for the constant are equalp, then the error is emitted within a warning object, as to accurately indicate the condition provided to the handler function. If the values are not equalp, then the condition is emitted as an error
- This source code can be added to one's ~/.sbclrc file, for convenience.
Works Consulted:
[1] Stack Overflow: SBCL: CONTINUE restart absent during COMPILE? (really was:absent in HANDLER-CASE)
[2] CLHS: HANDLER-BIND
[3] CLHS: HANDLER-CASE
[4] SBCL User Manual: Defining Constants
No comments:
Post a Comment