Elisp: Bindp в Лет - PullRequest
       6

Elisp: Bindp в Лет

3 голосов
/ 21 марта 2012

Как я могу проверить, что переменная определена раньше или нет внутри конструкции let?

 (let (((if (boundp 'a)
           'a
         'dummy) t))
   (message "I made this work"))

Я пытаюсь проверить, является ли a ограниченным ранее, если этоуже привязать его к t локально.иначе не волнует a.

Ответы [ 2 ]

5 голосов
/ 21 марта 2012

Код завершается с: (wrong-type-argument symbolp (if (boundp (quote a)) (quote a) (quote dummy))), указывая на то, что специальная форма let не оценивает этот аргумент (хотя этот список будет вычисляться как символ, сам список не является символом).

Вот простой, но некорректный альтернативный подход, который создает локальную привязку для a независимо, но затем связывает ее в этой локальной области, если она была изначально не связана.

(let ((a (if (boundp 'a) t nil)))
  (or a (makunbound 'a))
  ;; do things
  )

Недостаток в том, что если a изначально не был связан, вы бы хотели присвоить a в этой локальной области, чтобы пережить локальную область, и это не будет с этим подходом.

Сначала я думалвам нужно полностью отказаться от let, чтобы обойти эту проблему, и просто использовать что-то вроде этого:

(when (boundp 'a)
  (setq a-backup a
        a t))
;; do things
(when (boundp 'a-backup)
  (setq a a-backup)
  (makunbound 'a-backup))

Тогда я понял, что, как и во многих других случаях, ответом являются макросы:

(defmacro let-if-bound (var value &rest body)
  "Bind variable VAR to VALUE only if VAR is already bound."
  (declare (indent 2))
  `(if (boundp ',var)
       (let ((,var ,value))
         ,@body)
     (progn ,@body)))

(let-if-bound a t
  ;; do things
  )

(*) «Специальная форма» - это примитивная функция, специально помеченная так, что ее аргументы не все оцениваются.Большинство специальных форм определяют управляющие структуры или выполняют привязки переменных - то, что функции не могут делать.

Каждая специальная форма имеет свои собственные правила, для которых оцениваются аргументы и которые используются без оценки.Оценка конкретного аргумента может зависеть от результатов оценки других аргументов.

1 голос
/ 21 марта 2012

Я думаю, что "канонический" способ сделать это будет

(let ((bound (boundp 'a))
      (a t))
  (unless bound (makunbound 'a))
  ...blabla...)
...