Wie erkläre ich eine Variable für ignorierbar?

10

Wie vermeide ich Byte-Compiler-Warnungen Unused lexical variablein Funktionen, die mithilfe von Makros definiert wurden, die auf erweitert werden defun?

Beispielsweise verwendet das Makro defun-rcirc-commandin rcirc.eldie targetVariable, die nicht von mehreren Aufrufen verwendet wird.

In Common Lisp kann ich die ignorable Deklaration verwenden : (declare (ignorable target)).

Schlechte Lösungen:

  • Fügen Sie (setq target target)allen Benutzern, defun-rcirc-commanddie sie nicht verwenden target, etwas Ähnliches hinzu: Dazu müssen viele Makroaufrufe geändert werden.

  • Das Präfixieren der ignorierbaren Variablen mit einem Unterstrich - _target- hilft nicht, weil es _bedeutet ignore, nicht ignorable, dh wenn es verwendet wird, bekomme ich variable '_target' not left unused.

sds
quelle
Wenn Sie ihnen einen Unterstrich voranstellen, sollte dies der Fall sein.
Politza
@ Politza: _ bedeutet ignorieren, nicht ignorierbar
SDS
1
Möchten Sie das Makro ändern, um das Problem zu lösen? Sie könnten wahrscheinlich einfach (ignore VAR)für jedes defun-Argument ein vor die Erweiterung @ body setzen, wodurch die Fehler wahrscheinlich zum Schweigen gebracht werden.
Jordon Biondo

Antworten:

13

Die Art und Weise, wie ich das bisher gemacht habe, besteht darin, einen Aufruf der Form hinzuzufügen

(ignore <var>)

Dieser Funktionsaufruf wird entfernt, aber vorher zählt der Compiler ihn immer noch als Verwendung, sodass die Warnung "nicht verwendet" nicht ausgelöst wird.

Stefan
quelle
-1

Betrachtet man den Code, so scheint es, dass das Ziel keine globale Variable sein soll, sondern beim Aufruf an die erstellte Funktion übergeben wird. In diesem Fall ist es besser, es als lokales Symbol für das Makro zu erstellen. Ein einfaches Beispiel für ein Makro, das eine Funktion erstellt, die ein Argument akzeptiert und 10 hinzufügt:

(defmacro xxx (name)  
  ""
  (let ((target (make-symbol "target")))
  `(defun ,name (,target) (+ 10 ,target))))

Berufung

(xxx hamster)

führt zu einer Funktion namens hamster, die ein Argument akzeptiert.

Dann können Sie anrufen

(hamster 5)

und es wird zurückkehren 15.

Der Trick besteht darin, ein neues Symbol zu erstellen, das als Argument für die neue Funktion dient.

BEARBEITEN:

Ich habe immer gesehen, dass Sie, wenn Sie sich auf das generierte Symbol im übergebenen Body-Ausdruck beziehen, den Namen wie folgt in den Aufruf aufnehmen:

(defmacro xxx (name t2 &rest body)  
  ""
  (let ((t2-arg (make-symbol "target")))
  `(defun ,name (&optional ,t2-arg) 
     (let ((,t2 (or ,t2-arg 10)))
       ,@body))))

Was dann die Anrufe in:

(xxx hamster target (+ target 20))

wo

(hamster)

was zurückkommt 30und

(hamster 20)

kehrt zurück 40.

Zugegeben, das nervt mich immer, wenn ich Makros auf diese Weise schreibe, bis ich mir die Verwendung ansehe, in der ein Parameter deklariert und später verwendet wird.

M Smith
quelle
2
Der Hauptteil der Funktion wird an das Makro übergeben und muss in der Lage sein, darauf zu verweisen target. IOW, Ihr ausgezeichneter Vorschlag ist in diesem speziellen Fall nicht anwendbar.
SDS