Peter Siebel - Practical Common Lisp
Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Practical Common Lisp
- Автор:
- Издательство:Apress
- Жанр:
- Год:2005
- ISBN:1-59059-239-5
- Рейтинг книги:4 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 80
- 1
- 2
- 3
- 4
- 5
Practical Common Lisp: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
(:use :common-lisp)
(:export
:list-directory
:file-exists-p
:directory-pathname-p
:file-pathname-p
:pathname-as-directory
:pathname-as-file
:walk-directory
:directory-p
:file-p))
and LOAD
it. Then at the REPL or at the top of the file where you type the definitions from this chapter, type the following expression:
(in-package :com.gigamonkeys.pathnames)
In addition to avoiding name conflicts with symbols already available in CL-USER
, packaging the library this way also makes it easier to use in other code, as you'll see in several future chapters.
Listing a Directory
You can implement the function for listing a single directory, list-directory
, as a thin wrapper around the standard function DIRECTORY
. DIRECTORY
takes a special kind of pathname, called a wild pathname , that has one or more components containing the special value :wild
and returns a list of pathnames representing files in the file system that match the wild pathname. [167] Another special value, :wild-inferiors , can appear as part of the directory component of a wild pathname, but you won't need it in this chapter.
The matching algorithm—like most things having to do with the interaction between Lisp and a particular file system—isn't defined by the language standard, but most implementations on Unix and Windows follow the same basic scheme.
The DIRECTORY
function has two problems that you need to address with list-directory
. The main one is that certain aspects of its behavior differ fairly significantly between different Common Lisp implementations, even on the same operating system. The other is that while DIRECTORY
provides a powerful interface for listing files, to use it properly requires understanding some rather subtle points about the pathname abstraction. Between these subtleties and the idiosyncrasies of different implementations, actually writing portable code that uses DIRECTORY
to do something as simple as listing all the files and subdirectories in a single directory can be a frustrating experience. You can deal with those subtleties and idiosyncrasies once and for all, by writing list-directory
, and forget them thereafter.
One subtlety I discussed in Chapter 14 is the two ways to represent the name of a directory as a pathname: directory form and file form.
To get DIRECTORY
to return a list of files in /home/peter/
, you need to pass it a wild pathname whose directory component is the directory you want to list and whose name and type components are :wild
. Thus, to get a listing of the files in /home/peter/
, it might seem you could write this:
(directory (make-pathname :name :wild :type :wild :defaults home-dir))
where home-dir
is a pathname representing /home/peter/
. This would work if home-dir
were in directory form. But if it were in file form—for example, if it had been created by parsing the namestring "/home/peter"
—then that same expression would list all the files in /home
since the name component "peter"
would be replaced with :wild
.
To avoid having to worry about explicitly converting between representations, you can define list-directory
to accept a nonwild pathname in either form, which it will then convert to the appropriate wild pathname.
To help with this, you should define a few helper functions. One, component-present-p
, will test whether a given component of a pathname is "present," meaning neither NIL
nor the special value :unspecific
. [168] Implementations are allowed to return :unspecific instead of NIL as the value of pathname components in certain situations such as when the component isn't used by that implementation.
Another, directory-pathname-p
, tests whether a pathname is already in directory form, and the third, pathname-as-directory
, converts any pathname to a directory form pathname.
(defun component-present-p (value)
(and value (not (eql value :unspecific))))
(defun directory-pathname-p (p)
(and
(not (component-present-p (pathname-name p)))
(not (component-present-p (pathname-type p)))
p))
(defun pathname-as-directory (name)
(let ((pathname (pathname name)))
(when (wild-pathname-p pathname)
(error "Can't reliably convert wild pathnames."))
(if (not (directory-pathname-p name))
(make-pathname
:directory (append (or (pathname-directory pathname) (list :relative))
(list (file-namestring pathname)))
:name nil
:type nil
:defaults pathname)
pathname)))
Now it seems you could generate a wild pathname to pass to DIRECTORY
by calling MAKE-PATHNAME
with a directory form name returned by pathname-as-directory
. Unfortunately, it's not quite that simple, thanks to a quirk in CLISP's implementation of DIRECTORY
. In CLISP, DIRECTORY
won't return files with no extension unless the type component of the wildcard is NIL
rather than :wild
. So you can define a function, directory-wildcard
, that takes a pathname in either directory or file form and returns a proper wildcard for the given implementation using read-time conditionalization to make a pathname with a :wild
type component in all implementations except for CLISP and NIL
in CLISP.
(defun directory-wildcard (dirname)
(make-pathname
:name :wild
:type #-clisp :wild #+clisp nil
:defaults (pathname-as-directory dirname)))
Note how each read-time conditional operates at the level of a single expression After #-clisp
, the expression :wild
is either read or skipped; likewise, after #+clisp
, the NIL
is read or skipped.
Now you can take a first crack at the list-directory
function.
(defun list-directory (dirname)
(when (wild-pathname-p dirname)
(error "Can only list concrete directory names."))
(directory (directory-wildcard dirname)))
As it stands, this function would work in SBCL, CMUCL, and LispWorks. Unfortunately, a couple more implementation differences remain to be smoothed over. One is that not all implementations will return subdirectories of the given directory. Allegro, SBCL, CMUCL, and LispWorks do. OpenMCL doesn't by default but will if you pass DIRECTORY
a true value via the implementation-specific keyword argument :directories
. CLISP's DIRECTORY
returns subdirectories only when it's passed a wildcard pathname with :wild
as the last element of the directory component and NIL
name and type components. In this case, it returns only subdirectories, so you'll need to call DIRECTORY
twice with different wildcards and combine the results.
Интервал:
Закладка:
Похожие книги на «Practical Common Lisp»
Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.