Pathname host when merging relative pathnames
- From: dtc@xxxxxxxxxxxx
- Date: Sat, 12 May 2012 08:44:21 -0700 (PDT)
While looking into pathname issues in ASDF it has become apparent that the merging of relative pathnames is rather problematic. The usage in ASDF is to merge a relative pathname with a default base. The CL 'merge-pathnames is defined to merge a relative directory with the defaults base but will keep the specified host in this case. For example:
(merge-pathnames "TEST:;FILE.LISP" "/home/") => #P"TEST:HOME;FILE.LISP.NEWEST"
(merge-pathnames #p"file.lisp" #p"TEST:PATH;") => #P"/path/file.lisp"
The result is not usable because the host of the specified pathname is not necessarily applicable to the default base host.
CL requires the host in order to be able to parse the relative namestring. For example is not possible to parse the namestring ";FILE.LISP" alone.
The ASDF solution is to copy the default host when the specified directory is relative, and it defines a new function 'merge-pathnames* to do this.
CL defines *default-pathname-defaults*, and defines many functions to firstly merge an argument pathname with this, and also suggests this be the current working directory making. This makes it convenient to use relative pathnames for files based in the current working directory. However when working with multiple pathname hosts it becomes problematic using such relative pathnames because the host will not default along with the directory.
Having the host define the namestring format of the pathname seems a real plus for CL. URIs in contrast can not include a scheme in a URI reference (adding a scheme makes the URI absolute) so the full structure of a relative URI may not be parsed.
One workaround is to allow 'make-pathname to accept a host of 'nil and to not default this if supplied, so that a relative pathname could be created for which the standard merging rules would copy the host. However without the host the pathname may become unprintable, or at least fall back to a native format.
(merge-pathnames (make-pathname :host nil :defaults "TEST:;FILE.LISP") "/home/") => #P"/home/file.lisp"
(merge-pathnames (make-pathname :host nil :defaults "file.lisp") "TEST:PATH;") => #P"TEST:PATH;FILE.LISP"
Would much code break if an implementation just introduced a non-standard merging rule to copy over the host when the specified pathname directory is relative? For example:
(merge-pathnames "TEST:;FILE.LISP" "/home/") => #P"/home/file.lisp"
(merge-pathnames #p"file.lisp" #p"TEST:PATH;") => #P"TEST:PATH;FILE.LISP"
- Prev by Date: Re: Learning Lisp
- Next by Date: Re: Learning Lisp
- Previous by thread: Re: The LOOP macro
- Next by thread: Re: Pathname host when merging relative pathnames