函数名称作为Lisp中的字符串?

时间:2020-12-22 09:05:26

I have a big list of global variables that each have their own setup function. My goal is to go through this list, call each item's setup function, and generate some stats on the data loaded in the matching variable. However, what I'm trying now isn't working and I need help to make my program call the setup functions.

我有一个很大的全局变量列表,每个变量都有自己的设置功能。我的目标是遍历此列表,调用每个项目的设置函数,并生成匹配变量中加载的数据的一些统计信息。但是,我现在正在尝试的是不起作用,我需要帮助才能使我的程序调用设置功能。

The global variables and their setup functions are case-sensitive since this came from XML and is necessary for uniqueness.

全局变量及其设置函数区分大小写,因为它来自XML,并且是唯一性所必需的。

The data looks something like this:

数据看起来像这样:

'(ABCD ABC\d AB\c\d ...)

and the setup functions look like this:

并且设置功能如下所示:

(defun setup_ABCD...  
(defun setup_ABC\d...

I've tried concatenating them together and turning the resulting string into a function, but this interferes with the namespace of the previously loaded setup function. Here's how I tried to implement that:

我已经尝试将它们连接在一起并将结果字符串转换为函数,但这会干扰先前加载的设置函数的命名空间。以下是我尝试实现的方法:

(make-symbol (concatenate 'string "setup_" (symbol-name(first '(abc\d)))))

But using funcall on this doesn't work. How can I get a callable function from this?

但是在这上面使用funcall是行不通的。如何从中获得可调用的函数?

3 个解决方案

#1


12  

It's because MAKE-SYMBOL returns an uninterned symbol. You should use INTERN instead.

这是因为MAKE-SYMBOL返回一个未打开的符号。你应该使用INTERN。

#2


0  

I'd either use INTERN or (possibly, you'd have to profile to be 100% sure it's helpful) a helper function that does the string concatenation and the initial find, then caches the result in a hashtable (keyed off the original symbol). That may be faster than a pure INTERN/CONCATENATE solution, would potentially generate less transient garbage, but would probalby end up using more long-term storage.

我要么使用INTERN,要么(可能,你必须要100%确定它是有帮助的)辅助函数,它执行字符串连接和初始查找,然后将结果缓存在哈希表中(键入原始符号) )。这可能比纯粹的INTERN / CONCATENATE解决方案更快,可能会产生更少的瞬态垃圾,但最终会使用更长期的存储。

Something along the lines of:

有点像:

(defvar *symbol-function-map* (make-hash-table))

(defun lookup-symbol (symbol)
  (or (gethash symbol *symbol-function-map*)
      (let ((function-name (intern (concatenate 'string "setup_" (symbol-name symbol)))))
        (setf (gethash symbol *symbol-function-map*) (symbol-function function-name)))))

If you require the name of the function, rather than the function itself, leave out the call to SYMBOL-FUNCTION.

如果需要函数的名称而不是函数本身,请忽略对SYMBOL-FUNCTION的调用。

#3


0  

(funcall (read-from-string (concatenate 'string "setup_" (symbol-name(first '(abc\d))))))  

works too.

#1


12  

It's because MAKE-SYMBOL returns an uninterned symbol. You should use INTERN instead.

这是因为MAKE-SYMBOL返回一个未打开的符号。你应该使用INTERN。

#2


0  

I'd either use INTERN or (possibly, you'd have to profile to be 100% sure it's helpful) a helper function that does the string concatenation and the initial find, then caches the result in a hashtable (keyed off the original symbol). That may be faster than a pure INTERN/CONCATENATE solution, would potentially generate less transient garbage, but would probalby end up using more long-term storage.

我要么使用INTERN,要么(可能,你必须要100%确定它是有帮助的)辅助函数,它执行字符串连接和初始查找,然后将结果缓存在哈希表中(键入原始符号) )。这可能比纯粹的INTERN / CONCATENATE解决方案更快,可能会产生更少的瞬态垃圾,但最终会使用更长期的存储。

Something along the lines of:

有点像:

(defvar *symbol-function-map* (make-hash-table))

(defun lookup-symbol (symbol)
  (or (gethash symbol *symbol-function-map*)
      (let ((function-name (intern (concatenate 'string "setup_" (symbol-name symbol)))))
        (setf (gethash symbol *symbol-function-map*) (symbol-function function-name)))))

If you require the name of the function, rather than the function itself, leave out the call to SYMBOL-FUNCTION.

如果需要函数的名称而不是函数本身,请忽略对SYMBOL-FUNCTION的调用。

#3


0  

(funcall (read-from-string (concatenate 'string "setup_" (symbol-name(first '(abc\d))))))  

works too.