Quit vs Exit
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Quit vs Exit

Quit vs Exit

Ответ
Поиск в этой теме
Непрочитано 05.06.2006, 21:45 #1
Quit vs Exit
Tramp
 
Регистрация: 12.01.2006
Сообщений: 114

Уважаемые, кто-нибудь знает, в чём разница между лисповскими функциями (quit) и (exit)?
Просмотров: 5250
 
Непрочитано 06.06.2006, 07:26
#2
_Andre_

механизатор
 
Регистрация: 28.12.2004
Самара
Сообщений: 312
<phrase 1=


На сколько я представляю - никакой. Однако применять в программах эти функции для прерывания работы имхо не есть хорошо.
_Andre_ вне форума  
 
Непрочитано 06.06.2006, 09:12
#3
Profan


 
Регистрация: 25.12.2005
Москва
Сообщений: 13,627


Если посмотреть сообщения командной строки при выполнении функций quit и exit, то можно заметить:
;ошибка: завершить / выйти прервать- на русском языке и
;error: quit / exit abort - на английском языке. Отсюда можно сделать вывод, что
quit - это завершить,
exit - это выйти, а
abort - это прервать. Но функции abort вроде бы нет...
Profan вне форума  
 
Непрочитано 06.06.2006, 09:16
#4
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,408


Я в последнее время, если прописан обработчик ошибок, предпочитаю вызывать (vl-exit-with-error). не знаю, насколько это правильно, но пока вроде как с ума не сходило
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 06.06.2006, 09:19
#5
Pilot

Проектировщик свиноводство
 
Регистрация: 21.08.2003
Сообщений: 2,291


Использовать их можно. Но при этом должен быть грамотно написан обработчик ошибок для обнуления локальных переменных, которые после срабатывания (quit) или (exit) становятся глобальными.
Pilot вне форума  
 
Автор темы   Непрочитано 07.06.2006, 08:38
#6
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


Цитата:
Сообщение от kpblc
... если прописан обработчик ошибок ...
А можно пример такого обработчика?
Я понимаю, что если на этом форуме поискать хорошенько, то тут таких примеров достаточно, но если не затруднит... А то я, со своими познаниями в лиспе, не сразу и отличу :-)
Tramp вне форума  
 
Непрочитано 07.06.2006, 08:59
#7
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,408


Ок. Попробую рассказать
В общем-то суть проста. Ошибки выполнения обрабатываются встроенной функцией *error*. Поскольку это лисп, ее можно достаточно безболезненно переопределить. Суть такова: в объявлении функции
Код:
[Выделить все]
(defun myfunc())
в качестве локальных параметров (которые идут в объявлении после "/" указываем дополнительно слово *error* - это сделает обработчик ошибок локальным, т.е. работающим только внутри этой функции. Получим нечто типа:
Код:
[Выделить все]
(defun myfunc( / pt *error* _cmdecho_)
(defun *error*(msg); вот оно - описание обработчика ошибок
  (if _cmdecho_ (setvar "cmdecho" _cmdecho_)) ; Восстанавливаем системную переменную
  (command "_.undo" "_e") ; точка отмены
  (princ msg) ; печать сообщения об ошибке - можно и переопределить
  (princ) ; "тихий" выход, чтоб сообщение 2 раза не печаталось
  )
  (setq _cmdecho_ (getvar "cmdecho"))
  (if (setq pt (getpoint "\nУкажите точку <Выход> : "))
    (progn
      (setvar "cmdecho" 0)
      (command "_.undo" "_b")
      ;; Делаем чего хотим
      )
    )
  (command "_.undo" "_e")
  ;; И восстанавливаем системные переменные
  (if _cmdecho_ (setvar "cmdecho" _cmdecho_))
  (command "_.undo" "_e")
  (princ)
  )
Примерно в таком ключе. Естественно, что обработчик можно переопределить и глобально, но это требует некоторых дополнительных усилий по отслеживанию его актуальности, т.е. случайно не переназначить его
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 07.06.2006, 09:25
#8
Tramp


 
Регистрация: 12.01.2006
Сообщений: 114


Т.е. суть этого обработчика в возможности откатить все действия, которые можно прописать вместо строки ";; Делаем чего хотим "?
А нажатие пользователем клавиши ESC относится к разряду ошибок, или оно просто безоговорочно прерывает выполнение функции?
Tramp вне форума  
 
Непрочитано 07.06.2006, 09:33
#9
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,408


Ну как бы это сказать... В общем, к примеру. В процессе работы функции выполняются временные построения. Произошла ошибка. Временные примитивы надо посносить. Прописываем в обработчике. Там же, например, можно прописать восстановление состояния слоев, системных переменных, какие-либо дополнительные действия...
Нажатие Esc расценивается как вход в обработчик.
Пример почти универсального обработчика лежит на http://www.arcada.com.ua/forum/viewtopic.php?t=445 - если интеерсно
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 07.06.2006, 09:44
#10
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


kpblc почему-то умолчал или забыл? , что есть хороший ГОТОВЫЙ пример обработчика ошибок здесь
http://www.arcada.com.ua/forum/viewt...140818a1c968f1
Там определен стандартный обработчик ошибок kpblc-error
ВАЖНО! В ф-цию обработки ошибок всегда передается ОДИН параметр (msg) - сообщение об ошибке.
Пишется свой обработчик ошибок, например

Код:
[Выделить все]
;|==============================================
*    Стандартный обработчик ошибок AutoCAD
==============================================|;
(defun tramp-error (message)
;;;VLA указатель на текущий документ
 (or *kpblc-activedoc*
   (setq *kpblc-activedoc* (vla-get-activedocument (vlax-get-acad-object)))
)
;;;Прерываем активную команду  
(while (> (getvar "CMDACTIVE") 0)(command))
;;;Обрабатываем сообщение Автокада  
  (if (member message
        '("console break"      "Function cancelled"
    "Функция отменена"    "quit / exit abort"
    "выйти прервать"
    ) ;_list
        ) ;_member
    (princ "\nКоманда прервана пользователем")
    (princ
      (strcat "\ERRNO # "
        (itoa (getvar "ERRNO")) ;_itoa
        ": "
        message
        "\n"
        ) ;_strcat
      ) ;_princ
    ) ;_if
;;;Восстанавливаем системные переменные
  (kpblc-error-restore-sysvar)
;;;Это типа _UNDO _End
  (vla-endundomark *kpblc-activedoc*)
  (princ)
  ) ;_ end of defun
Недостающие ф-ции берешь из вышеуказанного места
Тогда заготовка твоей любой ф-ции будет выглядеть так

Код:
[Выделить все]
(defun myfunc ( / *error*)
;;;VLA указатель на текущий документ
  (or *kpblc-activedoc*
       (setq *kpblc-activedoc* (vla-get-activedocument (vlax-get-acad-object)))
   )
 (setq *error* tramp-error)  ;;;Переопределяем стандартный 
                                         ;;;обработчик ошибок
 (vla-endundomark *kpblc-activedoc*)
;;;Это типа _UNDO _Begin
 (vla-startundomark *kpblc-activedoc*)
;;;Сохраняем нужные системные переменные
 (kpblc-error-save-sysvar
      (list    	'("osmode")  ;;;Сохраняем OSMODE
	'("CLAYER")  ;;;Сохраняем CLAYER
               '("QAFLAGS" 0);;;Сохраняем QAFLAGS и инициализируем 0
               '("CMDECHO" 0);;;Сохраняем CMDECHO и инициализируем 0
               '("EXPERT" 5);;;Сохраняем EXPERT и инициализируем 5
               '("ANGBASE" 0) ;;;Направление 0 на ВОСТОК
                '("ANGDIR" 0) ;;;Отсчет углов против часовой стрелки
	'("UCSFOLLOW" 0)
      ))

;;; .......
;;; делаем чего хотим
;;; ......

;;;Если команда завершается чисто. восстанавливаем системные 
;;;переменные
;;;Если было аварийное завершение, то (kpblc-error-restore-sysvar)
;;;сработает в tramp-error, которая вызовется по указателю *error*
(kpblc-error-restore-sysvar)
;;;Это типа _UNDO _End
;;;Если быто аварийное завершение, то (vla-endundomark *kpblc-activedoc*)
;;; то бишь _UNDO _End поставится в tramp-error
;;;и все, что ты натворил можно будет отменить одним щелчком кнопки
(vla-endundomark *kpblc-activedoc*)
  )
VVA вне форума  
 
Непрочитано 07.06.2006, 09:54
#11
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Дополню kpblc №9. Ели произошла ошибка, то стандартный обработчик ошибок выводит сообщение об ошибке, обработчик tramp-error - выводит сообщение об ошибке, вызывает _UNDO _END, чтобы все, что было построено со времени вызова ф-ции можно было отменить одним нажатием кнопки. Если нужно сносить какие -либо врыменные примитивы, то их нужно накапливать в глобальной переменной и обрабатывать в tramp-error
Вот например как у нас

Код:
[Выделить все]
;|==============================================
*    Стандартный обработчик ошибок AutoCAD
==============================================|;
(defun mip-error (message)
 (or *kpblc-activedoc*
   (setq *kpblc-activedoc* (vla-get-activedocument (vlax-get-acad-object)))
)
;;;Прерываем активную команду  
(while (> (getvar "CMDACTIVE") 0)(command))  
  (if (member message
        '("console break"      "Function cancelled"
    "Функция отменена"    "quit / exit abort"
    "выйти прервать"
    ) ;_list
        ) ;_member
    (princ "\nКоманда прервана пользователем")
    (princ
      (strcat "\ERRNO # "
        (itoa (getvar "ERRNO")) ;_itoa
        ": "
        message
        "\n"
        ) ;_strcat
      ) ;_princ
    ) ;_if

;;;Удаляем временные притивы, сохраненные в *MIP-DELETE-ITEM*
  (mapcar '(lambda ( item)
	      (cond
		((and (= (type item) 'ENAME)
		      (entget item)
		      )
		 (entdel item)
		 )
		((and (= (type item) 'VLA-OBJECT)
		      (vlax-read-enabled-p item)
		      )
		 (vl-catch-all-apply 'vla-Delete (list item))
		 )
		(t nil)
		)
	      )
	  *MIP-DELETE-ITEM*
    )
  (setq *MIP-DELETE-ITEM* nil)
  ;;;Обнуляем все глобальные переменные
  (mapcar '(lambda (x)(set x nil)) *DWGRU_RESET_LIST*)
;;;Воостанавливаем предыдущю ПСК
  (if *MIP-UCS-PREV*   (command "_UCS" "_p"))
  (setq *MIP-UCS-PREV* nil)
  (kpblc-error-restore-sysvar)
  (_kpblc-layer-status-restore)
  (vla-endundomark *kpblc-activedoc*)
  (princ)
  ) ;_ end of defun
VVA вне форума  
 
Непрочитано 07.06.2006, 10:21
#12
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,202
<phrase 1=


как делаю я:

Допустим есть ваша Функция myfunc. Так вот чтоб в каждую новую функцию не вставлять этот обработчик ошибок, пишем функцию стандартного запуска my-com в которой через defun-q определяем *error*. Теперь можно запускать myfunc так: (my-com '(myfunc арг_1...арг_n)).
соответственно в my-com можно напихать еще целый ряд полезных вещей типа undo, обработки сис переменных, отрисованых или подсвеченых объектов и т.п. а в случае надобности в myfunc можно и переопределить *error* , добавив нужные функции к списку тела *error*.
__________________
apel.fas
Apelsinov вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Quit vs Exit