如何把变量名转化成字符串?
(intern "test")
;; => test
(some-func test)
;; => "test"
----
其实需求是这样的,我想在宏内把函数名也一起生成了
(defmacro hello (n)
`(defun ,(intern (concat "balabala-" n)) nil nil))
(hello "abc")
但是我觉得有点丑(因为看上去不像一个关键字),我想实现
(hello abc)
来生成 balabala-abc 的函数
如果有个内置的函数可以帮把 abc 转化成 “abc” 就好了。。。。
(symbol-name 'foo)
⇒ "foo"
quote 是用来确保不被求值。如果是为了处理返回值的话,不用 quote 也可以。这是 Lisp 的基础。
如无必要,勿用宏。为什么?举个例子:
(symbol-name-macro (getenv "PATH"))
=> "(getenv "PATH)"
1 个赞
谢谢,其实我的问题就是来自宏的。。。。
我想在宏内把函数名也一起生成了
(defmacro hello (n)
`(defun ,(intern (concat "balabala-" n)) nil (interactive) nil))
(hello "abc")
但是我觉得有点丑,我想实现
(hello abc)
来生成 balabala-abc 的函数
如果有个内置的函数可以帮把 abc 转化成 “abc” 就好了。。。。
(defmacro hello (n)
`(defun ,(intern (format "blabla-%S" n)) nil (interactive) nil))
;; => hello
(hello foo)
;; => blabla-foo
虽然 Emacs Lisp 里面的 format
没有 CL 的强,但是有时候还是很实用的。
1 个赞
如果再加上参数/函数体的支持,你的宏就要更复杂一些了,其实 defun
就是这样一个宏。
我感觉你需要的是这个:
;; blabla.el
(require 'names)
(define-namespace blabla-
;; ---------------------------------
(defun hello (s)
(message "Hello, %s!" s))
;; ---------------------------------
)
;; test.el
(require 'blabla')
(blabla-hello "World")
;; => "Hello, World!"
1 个赞
LdBeth
11
又造轮子……
命名空间是个习惯问题。而且对于 Emacs,共享一个命名空间有不少便利。
要想,当年 TECO 的 Q-寄存器 只有 2 字符的名称空间……
如果没有 quote, 按照lisp的求值规则, symbol 是作为变量来处理的,如果想将 symbol 作为 symbol 处理, 必须quote
宏是一种很奇怪的东西, 它很符合人性,也很反人类, 宏说白了就是简单的替换,是个人都会,但要实现有意义的替换, 就需要许多特殊的技巧,很反人类
2 个赞