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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Неприятные особенности использования запуска команд макросами кнопок

Неприятные особенности использования запуска команд макросами кнопок

Ответ
Поиск в этой теме
Непрочитано 05.06.2011, 20:08 #1
Неприятные особенности использования запуска команд макросами кнопок
swkx
 
Регистрация: 22.01.2010
Сообщений: 311

Общепринятый способ запуска команд кнопкой меню ^C^C(if (null C:<команда>)(load "<файл>"));<команда>;
в том числе и упомянутый VVA в статье "Как использовать лисп, опубликованный на форуме", иногда не совсем корректен. Ошибка возникает в случае, когда в тексте файлов двух вызываемых программ есть функции, имеющие одинаковое название, но выполняющие различные действия.

Пример. Имеем два файла test1.lsp и test2.lsp

Код:
[Выделить все]
 (defun c:test1 ()
	(func-alert)
)

(defun func-alert ()
	(alert "Test 1")
)

Код:
[Выделить все]
 (defun c:test2 ()
	(func-alert)
)

(defun func-alert ()
	(alert "Test 2")
)
Порядок действий в ком. строке Автокаде:
1. (load "C:\\test1.lsp")
2. test1 - работает правильно
3. (load "C:\\test2.lsp")
4. test2 - работает правильно
А дальше нюансики. Т.к. test1 уже загружена, просто выполняем её:
5. test1 - Ошибка ! Видим на экране окшко "Test 2", т.е. отработала (func-alert) из test2.

Вывод: создав две кнопки с макросами
^C^C(if (null C:test1)(load "C:\\test1.lsp"));test1;
и
^C^C(if (null C:test2)(load "C:\\test2.lsp"));test2;
и во всех похожих случаях имеем шанс нарваться на неприятности, которые усугубляются тем, что проявляются не всегда, а только при частом поочередном использовании кнопок в одном сеансе работы.

Вопрос: не лучше ли при современных объемах ОЗУ всегда использовать в качестве кода макроса конструкцию типа ^C^C(load "C:\\test1.lsp");test1; ?
Есть ли противопоказания у такого подхода ?
Просмотров: 7993
 
Непрочитано 05.06.2011, 20:30
#2
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


просто не используйте одинаковые имена функций...
при современных объемах ОЗУ лучше подгружать все скопом в файле mnl так ваше меню станет намного легче...
gomer вне форума  
 
Автор темы   Непрочитано 05.06.2011, 20:41
#3
swkx


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


Цитата:
Сообщение от gomer Посмотреть сообщение
просто не используйте одинаковые имена функций...
Не думаю, что это хорошая идея.
Описанный случай из практики. Заказчик попросил некоторую функцию. Я ему её предоставил. Примерно через месяц потребовалась ещё одна, похожая на первую, но несколько видоизменённая. Проще было её реализовать на базе первой. Разумеется, все имена внутренних функций остались прежними, только с другим наполнением.

А если прошел год, два, а не месяц ? Всё ведь не упомнишь...

У любого программиста есть сотни функций, кочующих из программы в программу иногда без изменений, иногда с незначительными правками.
Предлагаете всем им давать уникальные имена ?
swkx вне форума  
 
Непрочитано 05.06.2011, 21:02
#4
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


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

Цитата:
Сообщение от swkx Посмотреть сообщение
А если прошел год, два, а не месяц ? Всё ведь не упомнишь...
вот поэтому

Цитата:
Сообщение от gomer Посмотреть сообщение
просто не используйте одинаковые имена функций...
gomer вне форума  
 
Непрочитано 05.06.2011, 21:04
#5
VVA

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


Цитата:
Сообщение от swkx Посмотреть сообщение
У любого программиста есть сотни функций, кочующих из программы в программу иногда без изменений, иногда с незначительными правками
Это называется библиотека функций и имена у низкоуровненных функций не меняются. Объемы современны ОЗУ позволяют сильно не задумываться об оптимизации кода. Если не имеешь своей библиотеки, то можно функции объявлять локальными (т.е внутри функций). В таком случае время их жизни - время работы самой верхней ф-ции.
Код:
[Выделить все]
 
(defun c:test1 ()
    (defun func-alert ()
	    (alert "Test 1")
		  )
(func-alert)
 )

(defun c:test2 ()
    (defun func-alert ()
	    (alert "Test 2")
		  )
(func-alert)
 )
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 05.06.2011, 21:18
#6
Li6-D


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


И не забудь имена низкоуровневых функций указать в списке локальных переменных функции высокого уровня, иначе они станут глобальными
Li6-D вне форума  
 
Автор темы   Непрочитано 05.06.2011, 21:30
#7
swkx


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


VVA и Li6-D,

Локальные функции это, конечно, хорошо. Но как быть с уже написанной уймой программ без этих самых локальных функций ?

Повторю вопрос: есть ли подводные камни у способа вызова команды без проверки её предварительной загрузки, т.е.
^C^C(load "C:\\test1.lsp");test1; ?
swkx вне форума  
 
Непрочитано 05.06.2011, 21:35
#8
Кулик Алексей aka kpblc
Moderator

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


Теоретически есть - через atom-family (кажется, так) проверяешь существующие имена функций и переменных. Но намного проще и быстрее писать нормальный код, с использованием нормальных локальных переменных и функций.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 05.06.2011, 21:48
#9
swkx


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


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Но намного проще и быстрее писать нормальный код, с использованием нормальных локальных переменных и функций.
Конечно так лучше, но ведь на момент написания твой собственный код кажется тебе самым лучшим, а то, что он не такой уж и нормальный, выясняется уже потом)))
swkx вне форума  
 
Непрочитано 05.06.2011, 22:14
#10
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от swkx Посмотреть сообщение
Конечно так лучше, но ведь на момент написания твой собственный код кажется тебе самым лучшим, а то, что он не такой уж и нормальный, выясняется уже потом)))
Достаточно просто думать "а как я буду с ним разбираться через полгода-год" "САПР на баз AUtoCAD - как это делается". Настоятельно рекомендую. Дополнительно: http://autolisp.ru/2009/09/12/code-formatting/
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 05.06.2011, 22:45
#11
swkx


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


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Достаточно просто думать "а как я буду с ним разбираться через полгода-год"
Со своим кодом разобраться всегда можно, но ведь вполне возможна и следующая вполне типичная ситуация:
обычный продвинутый инженер-проектировщик обращается к кому-нибудь с просьбой написать программу, получает её, самостоятельно вешает её на кнопку и наслаждается жизнью. Через некоторое время обращается к другому программисту с очередным заданием, проделывает то же самое и наслаждается до тех пор, пока не нарвётся на описанную выше хрень.
А вероятность того, что в двух программах разных авторов окажутся НЕ локальные функции с одинаковыми именами, довольно высока. Например, вывод в Excel (toexcel), создания диалога "на лету" (make-dialog), перевода углов в радианы (dtor) и т.п. и т.п.
swkx вне форума  
 
Непрочитано 05.06.2011, 22:57
#12
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от swkx Посмотреть сообщение
А вероятность того, что в двух программах разных авторов окажутся НЕ локальные функции с одинаковыми именами, довольно высока
Зависит от автора
Цитата:
Сообщение от swkx Посмотреть сообщение
вывод в Excel
_kpblc-datas-export-to-excel
Цитата:
Сообщение от swkx Посмотреть сообщение
создания диалога "на лету"
fun_make-dlg, и ее в локальные
Цитата:
Сообщение от swkx Посмотреть сообщение
перевода углов в радианы
_kpblc-conv-degrees-to-radians или _kpblc-angle-convert. Попробуй найти еще подобные имена.
Еще раз говорю - внешняя команда, которую и вызывает пользователь, может иметь любое имя. Все остальное - потроха, про само существование которых пользователь зать не должен.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 05.06.2011, 23:29
#13
swkx


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


Алексей,

а причем тут твои функции ? Не все же ими пользуются. Рискну даже предположить, что не все заглядывают на этот форум, хотя это и трудно себе представить)))). Я говорю про двух разных программистов, программы которых окажутся у одного пользователя, который действительно не должен ничего знать про внутренности. И вот в этих двух программах вполне могут оказаться одноименные функции.
И для этого самого пользователя вызов команды ^C^C(load "C:\\test1.lsp");test1; - единственный надежный выход из положения.
swkx вне форума  
 
Непрочитано 06.06.2011, 00:01
#14
Li6-D


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


Если после (load "C:\\test1.lsp") ввести (load "C:\\test2.lsp"), то все глобальные переменные (включая функции), определенные в файле C:\test1.lsp будут заменены новыми из C:\test2.lsp при совпадении имен.
Тут ничего не поделаешь. Культурный программист постарается не использовать
глобальные переменные-функции или даст им уникальные имена
Например, Алексей добавляет префикс _kpblc.
Li6-D вне форума  
 
Непрочитано 06.06.2011, 00:17
#15
Кулик Алексей aka kpblc
Moderator

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


swkx, а я говорил про принципы именования функций и ни про что иное. Формируешь свой принцип и строго ему следуешь. Вот и все...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 06.06.2011, 06:52
#16
swkx


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


Li6-D и kpblc,

вы правы, до меня сразу не дошло, о чем говорил Алексей.
Однако это принципы, которыми нужно руководствоваться при написании будущих программ. Учту.
Хотя изначально речь шла о выходе из положения при уже свершившемся факте.
swkx вне форума  
 
Непрочитано 06.06.2011, 08:25
#17
Лиспер


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


А кто-то мешает прямо сейчас переделать пару кодов? Ну или сделать примерно так, как описано в http://autolisp.ru/2009/10/21/lisp-overloading/ ?
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 06.06.2011, 08:58
#18
E-degtyarev

Помогаю, кому делать нечего.
 
Регистрация: 27.03.2009
Русская деревня
Сообщений: 394


swhx, Загружаю Lisp-ы именно так, как ты предлагаешь (без IF) начиная где-то с 1997года. Никаких проблем не возникало, хотя теоретически их можно придумать. До 1997 года работал на машине АТ286 с "куриными мозгами" (хотя тогда это было круто). Там даже приходилось делать оверлеи и подгружать их. А современная машина несколько десятков килобайт lisp-a проглатывает не жуя. При этом не чихает и не кашляет. ИМХО.

PS: С точки зрения профессионала это конечно тупо, но я Lisp-любитель, кустарь-одиночка, и все себе заранее прощаю.

Последний раз редактировалось E-degtyarev, 06.06.2011 в 09:05.
E-degtyarev вне форума  
 
Автор темы   Непрочитано 06.06.2011, 09:20
#19
swkx


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


Цитата:
Сообщение от Лиспер Посмотреть сообщение
А кто-то мешает прямо сейчас переделать пару кодов?
Сейчас уже никто и ничто не мешает. А описание проблемы я увидел в почте на мобильном, причины и способ решения стали понятны сразу, но Автокада под руками не было, вот и пришлось посоветовать самый простой выход.

E-degtyarev,
я это и хотел услышать ))
Кстати, мне тоже приходилось использовать собственные лиспы на 286-м компе и 9-м автокаде. Выручала только функция (gc).
swkx вне форума  
 
Непрочитано 06.06.2011, 15:50
#20
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


swkx, у вас все лиспы находятся в корне диска с:? а если я захочу установить на другой диск? На каком-нибудь 10 уровне вглубь... как будет меню выглядеть?
как-то сделал функцию загрузки и запуска команды:
Код:
[Выделить все]
 (defun cdl-run (cmd fil / tmp)
;;; функция загруски и запуска команд
;;; (cdl-run 'ALIST "ALIST.LSP")
  (if (not (boundp (read (setq tmp (strcat "c:" (vl-princ-to-string cmd))))))
	  (progn (if *cdl_nomute* (prompt "\nЗагрузка..."))(load (findfile fil)))
  )
  (eval (read (strcat "(" tmp ")")))
)
вроде все хорошо... но когда изменяешь код программы, то естественно он не подгружается заново... но с другой стороны каждый раз грузить одно и тоже - не рационально... хотя бы чисто теоретически...
такой метод просто делает код меню вдвое меньше... (хм... еще кнопки можно по диску разбросать и совсем полный абзац будет...)
Для себя уяснил две вещи... в меню только команды и опции (это позволит набирать с команду клавиатуры сразу после загрузки меню), все иконки в библиотеке (так их не надо искать)...
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Неприятные особенности использования запуска команд макросами кнопок



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В русской версии AutoCAD 2010 SP1 32-bit файл Acad.PGP содержит ошибки. hwd Баги и пожелания в Autodesk 21 21.04.2010 20:27
Программное управление макросами кнопок Supermax Программирование 2 24.12.2007 14:07