I was trying to answer another SO question when I hit upon some very odd behavior. Here's my little test case:
(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")))))
where:
/tmp/foofoo
is a read-only file that I've visited and runmy-override-toggle-read-only
in./tmp/fooxxfoo
does not exist./tmp
is writable by the user I'm logged in as.
If I run tester-fn
in a buffer where my-override-mode-on-save
is set to t
then I get an unexpected result: XXX: no - YYY: no
. If I run tester-fn
while in some other buffer (e.g. scratch) I get the expected response in the minibuffer: XXX: no - YYY: yes
. Tracing the advice through the debugger shows it to be doing exactly what I think it should be doing, executing the parts I expect it to, skipping the parts I expect it to, returning the value I expect it to. However, tracing tester-fn
through the debugger shows very different values being returned (nil
& t
if the variable evaluates as nil, nil
& nil
if the variable evaluates as non-nil). The nil
& nil
return is really what I find bizarre.
I have no clue what's happening here. Anyone know why I'm not getting the results I expect?