Добавить новый переменный указатель для setf?

Я думаю, что это возможно в Common Lisp (через перегрузку setf), но не уверен насчет Emacs Lisp.

То, что я хочу сделать, было бы что-то вроде:

(setf (local variable) value)

где форма (local ...) вызовет некоторый код, который я написал, и вернет символ, который будет использоваться для установки его значения.

РЕДАКТИРОВАТЬ: Смотря на gv.el кажется советовать gv-get сделал бы работу, но, может быть, есть лучшая процедура для этого?

EDIT2: попробовал предложение от Стефана, закрыть, но не хорошо:(

(gv-define-setter local (value varname &optional buffer)
  `(with-current-buffer (or ,buffer (current-buffer))
     (setq ,varname ,value)))

который расширяется до:

(let* ((v bar))
 (with-current-buffer (or nil (current-buffer))
  (setq v 42)))

Очевидно, не то, что я хотел. Я пытался сделать это с советами, как указано выше, и с gv-define-expander, но слишком много цитат происходит, и я не могу найти способ потерять let часть выражения с избыточной подстановкой.

EDIT3:

Хорошо, если я что-то серьезно не испортил в области видимости или последовательности оценки значения, в которое будет установлена ​​переменная, похоже, это работает:

(gv-define-expander local
  (lambda (do &rest args)
    (let ((varname (first args))
          (buffer (or (second args) '(current-buffer)))
          (value (funcall do nil #'identity)))
      `(with-current-buffer ,buffer
         (setq ,varname ,value)))))

1 ответ

Решение

Там в gv-define-expander, gv-define-setter, а также gv-define-simple-setter (в порядке возрастания простоты использования).

Вы можете попробовать 100% гарантированный непроверенный код (обратите внимание, как я передаю with-current-buffer+setq в do вместо того, чтобы звонить do с фиктивными аргументами, чтобы у этих вещей был шанс работать при использовании с push).

(gv-define-expander local
  (lambda (do &rest varname &optional buffer)
    (macroexp-let2 nil b buffer
      (funcall do `(buffer-local-value ',varname ,b)
               (lambda (value)
                `(with-current-buffer ,b
                   (setq ,varname ,value)))))))
Другие вопросы по тегам