Я пытался ответить на еще один вопрос SO когда я столкнулся с очень странным поведением. Вот мой небольшой тестовый пример:
(make-variable-buffer-local
(defvar my-override-mode-on-save nil
"Can be set to automatically ignore read-only mode of a file when saving."))
(defadvice file-writable-p (around my-overide-file-writeable-p act)
"override file-writable-p if `my-override-mode-on-save' is set."
(or
my-override-mode-on-save
ad-do-it))
(defun my-override-toggle-read-only ()
"Toggle buffer's read-only status, keeping `my-override-mode-on-save' in sync."
(interactive)
(setq my-override-mode-on-save (not my-override-mode-on-save))
(toggle-read-only))
(defun tester-fn ()
(interactive)
(let ((xxx (file-writable-p "/tmp/foofoo"))
(yyy (file-writable-p "/tmp/fooxxfoo")))
(message (concat "XXX: " (if xxx "yes" "no") " - YYY: " (if yyy "yes" "no")))))
где:
/tmp/foofoo
— это файл только для чтения, который я посетил и запустилmy-override-toggle-read-only
./tmp/fooxxfoo
не существует./tmp
доступен для записи пользователю, под которым я зарегистрирован.
Если я запускаю tester-fn
в буфере, где my-override-mode-on-save
установлено на t
, я получаю неожиданный результат: XXX: no - YYY: no
. Если я запускаю tester-fn
, находясь в другом буфере (например, scratch), я получаю ожидаемый ответ в минибуфере: XXX: no - YYY: yes
. Отслеживание совета через отладчик показывает, что он делает именно то, что, по моему мнению, он должен делать, выполняя части, которые я от него ожидаю, пропуская части, которые я от него ожидаю, возвращая значение, которое я от него ожидаю. Однако отслеживание tester-fn
с помощью отладчика показывает, что возвращаются очень разные значения (nil
и t
, если переменная оценивается как ноль, nil
и nil
, если переменная оценивается как ненулевая). Возврат nil
и nil
действительно кажется мне странным.
Я понятия не имею, что здесь происходит. Кто-нибудь знает, почему я не получаю ожидаемых результатов?