В указанных условиях я хочу напечатать имя функции в этой функции. но я не знаю, как его получить. В C++ я могу использовать макрос препроцессора __FUNCTION__
. И что-то похожее в AutoLISP?
В AutoLISP возможно ли получить имя функции в теле функции?
Ответы (1)
Это определенно возможно. Рассмотрим две ситуации:
1) Вы пишете функцию.
Это должно быть легко, просто определите переменную с тем же именем, что и у функции, и все готово. (Как обсуждалось в комментариях выше.)
Вы даже можете использовать что-то более описательное, чем фактическое имя функции. (defun af () ...)
можно было бы назвать "Потрясающая функция" вместо "af".
Я бы также рекомендовал использовать стандартное форматирование постоянных значений: заглавные буквы с подчеркиванием для разделения слов. (setq FUNCTION_NAME "AwesomeFunction")
. (Это точно так же, как PI
, которое установлено для вас, и вы не должны его менять — это константа.)
2) Вы вызываете функцию, название которой вы можете не знать, пока код не запустится.
Некоторые примеры этого:
(apply someFunctionInThisVariable '(1 2 3))
(mapcar 'printTheNameOfAFunction '(+ setq 1+ foreach lambda))
(eval 'anotherFunctionInAVariable)
Чтобы напечатать имя функции, хранящейся в переменной, например, (setq function 'myFunction)
, вам нужно использовать функцию (vl-princ-to-string)
.
(vl-princ-to-string function) ;; Returns "MYFUNCTION"
(strcase (vl-princ-to-string function) T) ;; Returns "myfunction"
(princ
(strcase
(vl-princ-to-string function)
T
)
) ;; Command line reads: myfunction
Функцию (vl-princ-to-string)
можно использовать для любого печатаемого типа, и она всегда будет возвращать строку. Это здорово, если вы не знаете, есть ли у вас число или слово и т. д.
Надеюсь, это поможет!
P.S. Впервые я использовал эту технику, когда писал тестирующую функцию. Отправьте ему функцию и ожидаемое значение, и он проверит, работает ли он должным образом, включая печать имени функции как части строки. Очень полезно, если у вас есть время для настройки тестов.
__FUNCTION__
рассматривается как константа, определенная в верхней части функции, как в ответе 1 выше. Я могу понять, что копирование может сэкономить время, а не печатать имена функций, но даже в примере на этой странице было бы проще ввести имя функции, а не __FUNCTION__
. Ответ выше может потребовать немного больше работы, но он создает ту же функциональность: возможность использовать имя функции, внутри которой вы находитесь.
- person J.D. Sandifer; 23.03.2017
__FUNCTION__
или __func__
. Идентификатор __func__
неявно объявляется переводчиком как будто.... (курсив добавлен мной).
- person Tom Haws; 24.03.2017
(with-open-file (x "/tmp/foo") ...)
во что-то вроде(let ((x (open "/tmp/foo")) (unwind-protect (progn ...) (close x)))
. Я думаю, дело здесь в том, что вы можете написать макрос на Common Lisp, такой как defunx, который превратит(defunx name (...) ...)
во что-то вроде... - person Joshua Taylor   schedule 30.03.2016(defun name (...) (let ((__function__ 'name)) ...))
, что дало бы вам эффект, аналогичный тому, что вы могли бы получить в C. - person Joshua Taylor   schedule 30.03.2016defmacro
, что меня удивляет, потому что в XLisp он есть. На странице Википедии для AutoLisp говорится ... отсутствуют такие обычные функции LISP, как система макросов, ... поэтому я подозреваю, что макросов нет. - person Vatine   schedule 31.03.2016(defun example () (setq __FUNCTION__ "example" ) (print (strcat "this is the name of my function: " __FUNCTION__) ) )
Может быть, это может быть какое-то решение Спасибо всем за помощь - person CAD Developer   schedule 31.03.2016(let ((__function__ ...)) ...)
, а не setq. Вы, вероятно, не хотите, чтобы функция была глобальной... - person Joshua Taylor   schedule 31.03.2016__function__
должен быть локальным, но он должен бытьsetq
, потому что в AutoLISP у нас нетlet
- person CAD Developer   schedule 01.04.2016