5

Running the following in ielm in emacs -Q:

ELISP> (defun wh/expand-file-name (name &optional default-directory)
  (expand-file-name name default-directory))
wh/expand-file-name
ELISP> (expand-file-name "http://example.com" nil)
"/home/wilfred/http:/example.com"
ELISP> (wh/expand-file-name "http://example.com" nil)
#("/scp:http:/example.com" 1 4
  (tramp-default t))

Why do these two functions not return the same value?

  • I suspect it may relate to file-name-handler-alist, but I'm mystified as to how. – Wilfred Hughes Sep 18 '17 at 22:29
7

In short: dynamic binding.

It is maybe a little unfortunate that default-directory was used as the argument to expand-file-name.

Note the docstring:

(expand-file-name NAME &optional DEFAULT-DIRECTORY)

Convert filename NAME to absolute, and canonicalize it. Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative (does not start with slash or tilde); both the directory name and a directory’s file name are accepted. If DEFAULT-DIRECTORY is nil or missing, the current buffer’s value of ‘default-directory’ is used.

By dynamically binding a nil value for default-directory around the call to expand-file-name, that becomes both the argument passed by your function and the fall-back value which is used "If DEFAULT-DIRECTORY is nil or missing". That is the difference between the two variants, as normally the fall-back value would be a string.

n.b. C-hv default-directory

You would get the same result with:

(let ((default-directory nil))
  (expand-file-name "http://example.com" nil))

If you change the name of that argument in your function, this will stop happening. e.g.:

(defun wh/expand-file-name (name &optional defaultdir)
  (expand-file-name name defaultdir))

Note that expand-file-name itself is written in C and is not subject to this same behaviour, which is why it gets away with using that name as an argument, but you do not.

  • Bingo! and Bravo! – Drew Sep 18 '17 at 22:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.