Lisp - Как вызвать функцию внутри другой функции? - PullRequest
0 голосов
/ 24 июня 2018

Я пытаюсь вызвать следующую функцию:

(defun c:Add ()
    (setq a (getint "Enter a number to add 2 to it"))
    (setq a (+ a 2))
)

Внутри этой функции LOOPER:

(defun LOOPER (func)
    ;repeats 'func' until user enters 'no'
    (setq dummy "w")
    (while dummy
        (func) ;this is obviously the problem
        (setq order (getstring "\nContinue? (Y or N):"))
        (if (or (= order "N") (= order "n")) (setq dummy nil))
    )
)   

Как это:

(defun c:Adder ()
    (LOOPER (c:Add))
)

Как мнеобойти тот факт, что func не определена в LOOPER функции?

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Вы можете передать функцию в качестве аргумента другой функции, как показано в следующем примере:

(defun c:add ( / a )
    (if (setq a (getint "\nEnter a number to add 2 to it: "))
        (+ a 2)
    )
)

(defun looper ( func )
    (while
        (progn
            (initget "Y N")
            (/= "N" (getkword "\nContinue? [Y/N] <Y>: "))
        )
        (func)
    )
)

(defun c:adder ( )
    (looper c:add)
)

Здесь символ c:add вычисляется, чтобы получить указатель на определение функции, который затем привязывается к символу func в области действия функции looper. Таким образом, в рамках функции looper символы func и c:add оценивают одну и ту же функцию.

В качестве альтернативы, вы можете передать символ c:add в виде символа в кавычках, в этом случае значение символа func является символом c:add, который затем может быть оценен для получения функции:

(defun c:add ( / a )
    (if (setq a (getint "\nEnter a number to add 2 to it: "))
        (+ a 2)
    )
)

(defun looper ( func )
    (while
        (progn
            (initget "Y N")
            (/= "N" (getkword "\nContinue? [Y/N] <Y>: "))
        )
        ((eval func))
    )
)

(defun c:adder ( )
    (looper 'c:add)
)

Передача символа в кавычках в качестве функционального аргумента более соответствует стандартным функциям AutoLISP, таким как mapcar, apply и т. Д.

0 голосов
/ 24 июня 2018

Насколько я знаю, вы не можете отправлять имя функции в качестве параметра, но здесь я даю вам технику, которая может действовать аналогично.

У меня нет AutoCAD, установленной на моей машине, поэтому яЯ не могу проверить этот код.но вы можете удалить, если есть небольшая ошибка, или взять концепцию, чтобы вы могли реализовать свою собственную.

(defun c:Add ()
    (setq a (getint "Enter a number to add 2 to it"))
    (setq a (+ a 2))
)

(defun c:sub ()
    (setq a (getint "Enter a number to substract from 2:"))
    (setq a (-2 a))
)

(defun c:mul ()
    (setq a (getint "Enter a number to multiply with 2:"))
    (setq a (* a 2))
)


;----This function use to call other function from function name
;----Function name string is case sensitive
;----As per need you can Add function name to this function
(Defun callFunction(name)
(setq output nil)
;here you can add nested if condition but for simplicity I use If alone
(if (= name "C:Add")(setq output (C:Add)))
(if (= name "C:sub")(setq output (C:sub)))
(if (= name "C:mul")(setq output (C:mub)))
output
)

;----------Function end here



(defun LOOPER (func)
    ;repeats 'func' until user enters 'no'
    (setq dummy "w")
    (while dummy
        (callFunction func) ;Change here
        (setq order (getstring "\nContinue? (Y or N):"))
        (if (or (= order "N") (= order "n")) (setq dummy nil))
    )
)

Вам нравится запускать эту программу следующим образом:

(defun c:Adder ()
    (LOOPER ("c:Add"))
)

(defun c:substaker ()
    (LOOPER ("c:sub"))
)

(defun c:multiplyer ()
    (LOOPER ("c:mul"))
)

Надеюсь, это поможет:

...