объяснение с открытым файлом в терминах непрофессионала - PullRequest
7 голосов
/ 13 августа 2010

Я изучаю CL, и у меня минимальный опыт работы с другими языками. Может ли кто-нибудь объяснить мне в терминах непрофессионала, что это означает, особенно то, что здесь означает «вне», и как все это сочетается:

(defun save-db (filename)
  (with-open-file (out filename
                   :direction :output
                   :if-exists :supersede)
    (with-standard-io-syntax
      (print *db* out))))

В основном, бит, который я не понимаю, "отсутствует", но объяснение всего этого было бы неплохо.

Спасибо

Ответы [ 2 ]

5 голосов
/ 13 августа 2010

out - переменная потока, связанная с открытым файлом.with-open-file гарантирует, что файл открыт внутри области и закрыт вне области независимо от того, как вы выходите.

1 голос
/ 13 августа 2010

В дополнение к ddyer, вы также можете использовать MACROEXPAND или MACROEXPAND-1, чтобы увидеть, что WITH-OPEN-FILE делает:

(macroexpand '(with-open-file (out filename
                               :direction :output
                               :if-exists :supersede)
               (with-standard-io-syntax
                 (print *db* out))))

говорит нам

(LET ((OUT (OPEN FILENAME :DIRECTION :OUTPUT :IF-EXISTS :SUPERSEDE)) (#:G748 T))
  (UNWIND-PROTECT
      (MULTIPLE-VALUE-PROG1 (PROGN (WITH-STANDARD-IO-SYNTAX (PRINT *DB* OUT)))
        (SETQ #:G748 NIL))
    (WHEN OUT (CLOSE OUT :ABORT #:G748))))

Мы можемувидим, что мы открываем файл с именем filename, назначаем поток открытых файлов на out и что-то делаем.Если случится что-то плохое, UNWIND-PROTECT будет CLOSE потоком, если он не будет nil.

Переменная #:G748 является символом GENSYM ed (так что это свежий, непереданный,условное обозначение).Если при записи файла ничего не происходит неправильно, мы устанавливаем #:G748 в nil.

Таким образом, когда мы CLOSE в потоке, если что-то пошло не так, #:G748 будет T, поэтому CLOSE будет пытаться убрать любые побочные эффекты создания потока.

...