macro怎样调用eval过得参数?

(defmacro my-make-select-tab-func (num)
  (let* ((number (eval num)) ; eval的结果是我想要的
;; (number num) ; 现在的实际结果,但会报错
		 (func-name (intern (format "my-select-tab-%s" number))))
	`(defun ,func-name ()
	   (interactive)
	   (tab-bar-select-tab ,number))))

(dolist (i (range 0 10)) ;  range是自己写的函数约等于python里的range
  (my-make-select-tab-func i)) ; 好像不eval不行

想生成一些函数然后define-key绑定掉,但发现macro不会eval参数,所以不手动eval会生成 类似my-select-tab-i的函数。

如果手动eval了,函数生成是生成了,但是会在启动时卡顿且报一个Eager macro-expansion failure: (void-variable i) 的错误。

虽然官方不推荐这么做,gnu manual,但这里这么做我觉得比较优雅(?)

实际结果
(my-select-tab): my-select-tab                                                                                                                                                
my-select-tab-i                                                                                                                                                              ```

我想要的
(my-selec): my-select-tab                                                                                                                                                     
my-select-tab-0                                                                                                                                                               
my-select-tab-1                                                                                                                                                               
my-select-tab-2                                                                                                                                                               
my-select-tab-3                                                                                                                                                               
my-select-tab-4                                                                                                                                                               
my-select-tab-5                                                                                                                                                               
my-select-tab-6                                                                                                                                                               
my-select-tab-7                                                                                                                                                               
my-select-tab-8                 
(defmacro my-make-select-tab-func (num)
  (let ((number num)
        (func-name (intern (format "my-select-tab-%s" num))))
    `(defun ,func-name ()
       (interactive)
       (tab-bar-select-tab ,number))))

fset (which is a function)取代 defun (macro),自己看下 defun 是咋实现的。函数体用 closure 好了。

其实这个场景可以直接循环绑定一些 lambda 函数就好了

(lambda () (interactive) ...)

这样也是可以的。

应该用defalias,用fset还得用eval-and-compile

手动 eval 的时候 lexical-binding 是关闭的,所以通过(仅仅不报错而已,结果并不符合预期)。放在文件里执行的时候 lexical-binding 开启了,所以报错。

都报错了,何谈优雅。

numbernum 没差,传进来的 i 还是 i

啊对,忽略了,他传进来的是 i 不是 数字来着x

一语惊醒梦中人,好像let包裹一下直接把词法作用域关掉就好(

好像这么写就好了,稍微之前有点犯蠢…

(dolist (i (range 1 10))
  (eval `(my-make-select-tab-func ,i)))

对的,macro的问题在于传什么进去都不会被eval,那么就要在执行(my-make-select-tab-func i)之前把ieval出来,即调整(my-make-select-tab-func i)把里面的i换成i的值,eval a backquoted form能做到这点。