Критика и улучшить файл читать обычные


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun read-sim-file (filename)
  "Reads file.
File is presumed to be the output from a simulation.

Returns lines from the simulation as a list of strings

We throw an error if TRAP ET is detected.

Lines with DBG_INT are ignored."
  (let ((file-text-list (split "\\n"
                   (batteries:read-text-file filename)))
    (return_list '()))

    (loop for line in file-text-list do
     (cond ((scan "DBG_INT" line)
        )  ; intentional newline.
           ((scan "TRAP ET" line)
        (error "Trap ET detected"))
           (t
        ;; There's got to be a cleaner method here.
        (setf return_list (append return_list (list line))))))
    return_list))

Этот код-это некрасиво. В частности, (Х чтения (дописывать х г)) идиома чувствует себя ужасно неуклюжим.

Комментарии о том, как сделать это более красиво?

Возможно, удалить-если?



367
2
задан 27 июня 2011 в 10:06 Источник Поделиться
Комментарии
1 ответ

На первый взгляд, вы ищете петлис собрать предложение.

(defun read-sim-file (filename)
(let ((file-text-list (split "\\n" (batteries:read-text-file filename))))
(loop for line in file-text-list
when (scan "TRAP ET" line)
do (error "Trap ET detected o_o")
unless (scan "DBG_INT" line)
collect line)))

На второй взгляд, вы можете сделать это намного более эффективно, используя с-открыть-файл вместо того, чтобы ломать свой входной файл в список (это должно сэкономить вам два перехода указанного файла)

(defun read-sim-file (filename)
(with-open-file (stream filename)
(loop for line = (read-line stream nil 'eof) until (eq line 'eof)
when (scan "TRAP ET" line)
do (error "Trap ET detected ಠ_ಠ")
unless (scan "DBG_INT" line)
collect line)))

Первый-довольно простой цикл директивы, второй-почти verbatum пример из ХЛ Поваренная книга "файлы" раздел (весь поваренная книга содержит много других полезных рецептов тоже).

Просто как заметка на полях, стараюсь отступ правильно. Это было более трудным, чем это должно было читать вашу первоначальную программу. Если вы когда-нибудь ловили себя оставляя такие комментарии ;; умышленное строки, задуматься о том, что вы только что написали.


Теперь, что я имел полноценный сон, позволяет взять новый только для образовательных целей.

  (with-open-file (stream filename)

Эта строка открывает файл и создает дескриптор для имени потока. Ничего фактически не было еще читать, вы только что получили поток, чтобы вытащить из.

    (loop for line = (read-line stream nil 'eof) until (eq line 'eof)

петля имеет несколько неочевидных директив. Это один из них (и, кстати, причина того, что некоторые lispers предпочитают нестандартные итерации модуль; есть ощущение, что инфиксной нотации не Lispy достаточно. Я не согласен, просто хотел указать на это).

читать он-лайн принимает поток и несколько вариантов и возвращает первую строку из этого потока. (читать он-лайн трансляция Нил 'ВФ) означает "прочесть следующую строку из потока, не ошибка в конце файла маркер (это ноль) и вернуть символ конец файла EOF при достижении конца файла.

Полную линию затем считывает "перебрать строки в поток , пока вы не нажмете 'ВФ".

      when (scan "TRAP ET" line)
do (error "Trap ET detected ಠ_ಠ")

петли и условные директивы, поэтому вам не нужно прибегать к усл здесь. если, еще, когда и если все допустимые формы.

      unless (scan "DBG_INT" line)

Кстати , есливы можете использовать его, чтобы пропустить "DBG_INT" линии без выделения отдельным пунктом для них.

        collect line))

Это не то же самое

     (setf tmp (append return_list (list line)))

который должен сказать, она создает список, в котором элементы собираются в порядке, в котором они встречаются (хотя есть не является фактическим именем переменной). В петле форма также возвращает все, что вы собрали, если это последний пункт в заявлении (так что вам не нужно явно вернуть его).

2
ответ дан 3 сентября 2011 в 04:09 Источник Поделиться