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-warning
s, 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 defun
s 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