common lisp - sbcl - how to muffle "undefined variable" warning? -
i can't figure out how sb-ext:muffle-conditions. want this:
(declaim #+sbcl(sb-ext:muffle-conditions sb-kernel:redefinition-warning)) except want muffle "undefined variable" warning instead of redefinition, of course.
if knows parameter or has link documentation/various options sb-ext:muffle-conditions, please share :) thanks
i'm not sure whether you'll able muffle type of warning specifically, @ least class name. tracing warn, can idea of sbcl doing. instance, happens in redefinition case:
* (trace warn) (warn) * (defun foo () nil) foo * (defun foo () nil) 0: (warn sb-kernel:redefinition-with-defun :name foo :new-function #<function foo {10041fa989}> :new-location #s(sb-c:definition-source-location :namestring nil :toplevel-form-number nil :plist nil)) style-warning: redefining common-lisp-user::foo in defun 0: warn returned nil foo warn getting called class sb-kernel:redefinition-with-defun , arguments class designator, , warning signaled has specific class type. being able muffle based on particular class type makes muffling easier.
now, happens in case of undefined variable:
* (defun foo2 () x) 0: (warn "undefined ~(~a~): ~s" :variable x) ; in: defun foo2 ; (block foo2 x) ; ; caught warning: ; undefined variable: x 0: warn returned nil ; ; compilation unit finished ; undefined variable: ; x ; caught 1 warning condition foo2 warn being called format string , arguments, warning being signaled simple-warning. now, can still muffle it, it's bit more complicated.
according sbcl manual section, 3.1.1 controlling verbosity, sb-ext:muffle-conditions using muffle-warning restart. because undefined variable warning simple-warning, , don't want muffle all simple-warnings, we'll need bit sneaky , inspect condition using handler specified handler bind. since we've seen arguments warn getting called with, can specific in catch. can recognize these warnings undefined-variable-warning-p:
(defun undefined-variable-warning-p (w) (let ((control (simple-condition-format-control w)) (arguments (simple-condition-format-arguments w))) (and (= 2 (length arguments)) (eq :variable (first arguments)) (string= control "undefined ~(~a~): ~s")))) now can wrap compilation forms in appropriate handler-bind. instance, let's @ (compile nil (lambda () x)) , without handler:
cl-user> (compile nil '(lambda () x)) ; ; caught warning: ; undefined variable: x ; ; compilation unit finished ; undefined variable: ; x ; caught 1 warning condition #<function (lambda ()) {1003aa4f89}> t t cl-user> (handler-bind ((simple-warning #'(lambda (w) (when (undefined-variable-warning-p w) (invoke-restart 'muffle-warning))))) (compile nil '(lambda () x))) #<function (lambda ()) {1003b737e9}> nil nil we've succeeded in compiling function , muting undefined variable warning. however, aware can't wrap defuns in this. e.g.,
cl-user> (handler-bind ((simple-warning #'(lambda (w) (when (undefined-variable-warning-p w) (invoke-restart 'muffle-warning))))) (defun some-function () x)) ; in: defun some-function ; (defun some-function () x) ; --> progn eval-when sb-impl::%defun sb-int:named-lambda function ; ==> ; (block some-function x) ; ; caught warning: ; undefined variable: x ; ; compilation unit finished ; undefined variable: ; x ; caught 1 warning condition some-function however, if eval same defun (but i'm not saying should), warning muffled:
cl-user> (handler-bind ((simple-warning #'(lambda (w) (when (undefined-variable-warning-p w) (invoke-restart 'muffle-warning))))) (eval '(defun some-other-function () x))) some-other-function i'm not sure why is, hope may able elaborate in comments. suspect comes sbcl compiling forms on repl, meaning body of defun getting compiled before entire form run, , compilation happening before handler in place.
Comments
Post a Comment