Некоторые особенности работы lisp

Не думал, что надо про такое писать, но последняя неделя обсуждений на форуме dwg.ru показала, что некоторые базовые элементы лучше показать сразу.

Все нижесказанное касается только lisp-кодов для обычного (не консольного) AutoCAD. VBA, .NET, arx живут своей жизнью, их затрагивать я не собираюсь. Учитывая, что scr-коды я не использовал никогда, по их поводу ничего сказать не смогу.

  1. Код будет работать только в том случае, если он загружен
  2. Код будет срабатывать только в том случае, если он вызывается
  3. Код lisp по умолчанию срабатывает только в текущем документе. Для обработки неактивного документа необходимо использовать танцы с бубнами
  4. Следствие: переход (активация) в другой документ останавливает выполнение lisp-кода
  5. Наличие внедокументных переменных само по себе ничего не значит: необходим загруженный код, который сможет к ним обратиться и обработать
  6. Команды срабатывают только в текущем документе
  7. Функции entmake, entmakex срабатывают только в текущем документе

Что самое унылое - попытка выполнить (command "_.-open" ...) или (vla-open ...), как правило, приводит к смене активного документа. Следовательно, для продолжения работы кода придется изыскивать средства для решения перечисленных выше пунктов.

(vla-add (vla-get-documents ...)) файл, может быть, и откроет, и, если повезет, даже не активирует новый документ - но принципиально решение ничем не будет отличаться от использования ObjectDBX.

Автоматическая загрузка кода может быть реализована (материал для размышления - Война с меню и Последовательность загрузки приложений). Самовызов кода (http://autolisp.ru/2012/06/10/app-autoload-another-path/ и http://autolisp.ru/2014/10/21/execute-lisp-at-opening-dwg/ - тоже. Но для этого надо сильно приложить усилия и провести массу экспериментов. И это выходит за пределы коротенькой статьи.



Комментарии

Есть 4 коммент. к “Некоторые особенности работы lisp”
  1. gomer пишет:

    Поправка: лисп-код ВСЕГДА "срабатывает " при загрузке! Причем если в коде есть ошибка, то интерпретатор вернет ее и прервет загрузку кода. Таким образом часть функций может быть не определена. Скажем так "срабатывает" - это некорректное определение. Код может вызываться и выполняться. При загрузке кода он выполняется. Вызывается из командной строки, меню и т.д. Более того, если в коде файла прописать безусловную загрузку самого себя, гарантированно получим вылет при загрузке. Поэтому я никогда ничего не выполняю при загрузке автокада, достаточно загрузить код, чтобы пользователь мог его вызвать.

  2. Кулик Алексей aka kpblc пишет:

    >> если в коде есть ошибка, то интерпретатор вернет ее и прервет загрузку кода
    Если в коде есть синтаксическая ошибка, то код не будет загружен - это да. Другие ошибки отслеживаться не будут.
    Остальное не понял, хотя перечитывал не один и не два раза. Постарайся выразиться яснее, с учетом того, что прописано в тексте ))

  3. gomer пишет:

    Допустим есть три файла a.lsp b.lsp и c.lsp. в первом всего три строчки
    (nentselp '(0 0 0))
    (/ 1 0)
    (/ 0 1)
    При загрузке a.lsp получим
    Команда: (LOAD "D:/VLISP/a - копия.lsp") ; ошибка: деление на нуль
    То есть все, что после ошибки игнорируется. Синтаксических ошибок в коде нет... Более того, переменная ERRNO примет значение 7 (Object selection: pick failed)

    В файле b.lsp всего одна строчка
    (load "c.lsp")
    В файле c.lsp всего одна строчка
    (load "b.lsp")
    Формально никаких ошибок нет в коде обеих файлов, но автокад упадет из-за рекурсивной загрузки этих двух лиспов.

    Как правило в лисп-коде хранятся только определения функций, то есть вызывается только функция defun, поэтому возникает заблуждение, что лисп-код при загрузке не выполняется. Но если вставить в код вызов определенной в файле функции после описания функции, то она выполнится, если до, то произойдет ошибка (функция не определена).
    На самом деле при загрузке лисп-файла лисп-код выполняется полностью и возвращается результат последнего вычисленного выражения. Если в коде есть ошибка, то загрузка/выполнение кода останавливается, возвращается сообщение об ошибке и переменная ERRNO получает соответствующее значение.
    С другой стороны, действительно, функция defun воспринимает "тело функции", свой "последний аргумент", как единое выражение, которое не вычисляется, и проверяется только его синтаксис. Оно будет вычислено только при вызове определенной функции.
    И еще не стоит забывать про функцию autoload которая загружает автоматически нужный лисп при вызове команды.
    Ну и наконец, использование функции defun абсолютно не обязательно, если вы не сторонник структурного программирования. Достаточно на макрос повесить функцию load с соответствующим файлом и его код выполнится при нажатии на соответствующую кнопку.

  4. Кулик Алексей aka kpblc пишет:

    А я где-то тут говорил о нескольких lsp? Я говорил о самовызове кода / функции? Я разве говорил о структуре lsp-файлов, последовательности их загрузки и т.п.?
    Ладно, gomer, предлагаю считать, что ты крут и недосягаем :) Я не хочу спорить.

Поделитесь своим мнением


Я не робот.