Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Emacs 在elisp中,如何将反引号应用于从文件读取的列表_Emacs_Elisp - Fatal编程技术网

Emacs 在elisp中,如何将反引号应用于从文件读取的列表

Emacs 在elisp中,如何将反引号应用于从文件读取的列表,emacs,elisp,Emacs,Elisp,我想要一个大的列表(想想emacs主题中的faces),并将其分解成单独文件中的小列表。我遇到的问题是,一旦读入列表,就将其应用到列表中 下面是我用来试验解决方案的代码: (defvar x 23) (defun read-from-file (file) (with-temp-buffer (insert-file-contents file) (read (current-buffer)))) ;;(defun apply-macro (macro arg-list)

我想要一个大的列表(想想emacs主题中的faces),并将其分解成单独文件中的小列表。我遇到的问题是,一旦读入列表,就将其应用到列表中

下面是我用来试验解决方案的代码:

(defvar x 23)

(defun read-from-file (file)
  (with-temp-buffer
    (insert-file-contents file)
    (read (current-buffer))))

;;(defun apply-macro (macro arg-list)
;;  (eval
;;   `(,macro ,@(loop for arg in arg-list
;;                    collect `(quote ,arg)))))

(defvar parts (mapcar 'read-from-file (directory-files "./parts/" "parts/" "\.part$")))

;;(apply-macro 'backquote parts)

parts 
此代码依赖于名为
parts/
的子目录中的“数据”文件。以下是一些示例:

  • parts/one.part

    `(“一”“二”“三”)(“十”,x“十二”)
    注意:本例中的
    ,x
    。我希望在从文件中读取表达式后对其求值。
  • parts/two.part

    (“四”“五”“六”)(2 4 6)(9 87 6))
  • 部分/3.部分

    (“七”“八”“九”))
  • 读取“部件”文件没有问题。
    (defvar parts(mapcar…)

    问题是,一旦我在
    parts
    变量中有了列表,我就找不到一种方法来计算
    ,x
    ,因为如果整个列表被反引用,而不是从文件中读取的话

    我在中尝试了建议。您可以在上面的代码中看到注释掉的
    apply macro
    函数。当我运行它时,我得到:

    Debugger entered--Lisp error: (wrong-number-of-arguments #[(structure) "\301!A\207" [structure backquote-process] 2 1628852] 3)
      #[(structure) "\301!A\207" [structure backquote-process] 2 1628852]((quote (\` (("one" "two" "three") ("ten" (\, x) "twelve")))) (quote (("seven" "eight" "nine"))) (quote (("four" "five" "six") (2 4 6) (9 87 6))))
      (backquote (quote (\` (("one" "two" "three") ("ten" (\, x) "twelve")))) (quote (("seven" "eight" "nine"))) (quote (("four" "five" "six") (2 4 6) (9 87 6))))
      eval((backquote (quote (\` (("one" "two" "three") ("ten" (\, x) "twelve")))) (quote (("seven" "eight" "nine"))) (quote (("four" "five" "six") (2 4 6) (9 87 6)))))
      apply-macro(backquote ((\` (("one" "two" "three") ("ten" (\, x) "twelve"))) (("seven" "eight" "nine")) (("four" "five" "six") (2 4 6) (9 87 6))))
      eval-region(648 678 t #[257 "\300\242b\210\301\207" [(678) (apply-macro (quote backquote) parts)] 2 "\n\n(fn IGNORE)"])  ; Reading at buffer position 651
      eval-defun-2()
      #[257 "\211\203
    

    反引号做了一些有趣的事情。在Emacs lisp中,读取准引号列表返回的值是以下结构的列表:

    ELISP> (defvar x (car (read-from-string "`(1 2 ,x)")))
    
    ELISP> (car x)
    \`
    
    ELISP> (cdr x)
    ((1 2
        (\, x)))
    
    ELISP> (caddr (cadr x))
    (\, x)
    
    ELISP> (consp (caddr (cadr x)))
    t
    
    因此,如果您打算使用准引号列表,您可能需要自己执行替换。例如,您可以执行以下操作:

    (defun replace-item (item new-item seq)
      (let ((found-item (member item seq)))
        (when found-item
          (setf (car found-item) new-item))
        seq))
    
    
    ELISP> (replace-item '(\, x) 'z (cadr x))
    (1 2 z)
    
    PS.Common Lisp使用逗号字符做了一些奇怪的事情,在读取相同的列表
    后,X
    成为
    SB-IMPL::comma
    类型的对象(在SBCL中):它既不是符号,也不是对

    PPS。不知何故,读者计算器会特别处理这些准引号和逗号,以至于组合
    (eval(read))
    不会产生与内部计算器相同的结果

    有用的东西 在使用反引号和逗号的时候,我发现下面的方法很有效,尽管这是一个相当复杂的技巧

    首先,不要重复引用你的结构:它不会造成任何伤害,但也不会引入任何东西

    当您读取它时(使用文件中的
    read
    或字符串中的
    read
    ),它将转换为:

    ELISP> (setq x (car (read-from-string "(a b ,c)")))
    (a b
       (\, c))
    
    现在,神奇的是:有一个宏
    backquote
    进行替换,但它接受一个结构:它不计算其参数,因此要使其作用于
    x
    必须执行以下操作:

    ELISP> (let ((c 10)) (eval `(backquote ,x)))
    (a b 10)
    
    如您所见,
    (\,c)
    已被所需的
    c
    的本地绑定所取代

    购买力平价。人们会期望从字符串
    (ab,c)”
    中读取将产生
    (反引号(ab,c))`但事实并非如此


    我希望这能提供答案。

    谢谢。看起来我会为我要替换的每个符号调用
    replace item
    调用。例如,如果文件中的列表包含,x,y,那么我需要为每个符号调用replace item。我想我可以找到所有需要替换的逗号部分,并映射到它们或其他符号上ng,但如果有一种应用反引号的方法会更好。@HenryBone我想我找到了让Elisp做你想做的事情的方法:我已经更新了答案。@HenryBone事实上,它可以更简单:
    (let((c 10))(eval(car(从字符串“
    (a b,c)”)=>(a b 10)`Thank you@mobiuseng.have tick.:-)