【问题标题】:Idiomatic way serialization in emacs lispemacs lisp中的惯用方式序列化
【发布时间】:2016-03-24 05:34:26
【问题描述】:

目前我正在研究一种 elisp 主要模式,该模式在会话中使用哈希表。所以每次初始化主模式时,表都会被加载到内存中。在会话期间和结束时,它们被写入文件。我当前的实现以以下方式写入数据:

(with-temp-buffer
  (prin1 hash-table (current-buffer))
  (write-file ("path/to/file.el"))))

在会话开始时加载数据是通过读取完成的,如下所示:

(setq name-of-table (car
        (read-from-string
         (with-temp-buffer
           (insert-file-contents path-of-file)
           (buffer-substring-no-properties
        (point-min)
        (point-max))))))))

它有效,但我觉得这不是最漂亮的方式。我的目标是:我希望这个主要模式变成一个漂亮的干净包,将它自己的数据存储在存储包的其他数据的文件夹中。

【问题讨论】:

  • 将初始化程序放入您正在评估的 Lisp 代码中?让您在阅读时免于做任何复杂的事情 - 然后您只需 eval-buffer 并且您在编写时添加的代码只需为 (setq variable 和最后的结束括号。
  • 看起来简单可行。 ^^ 我会看看它是如何工作的,如果进展顺利,我会将您的帖子标记为答案。 :)
  • 无需转成字符串,只需在临时缓冲区中做(read (current-buffer))即可。

标签: emacs lisp elisp


【解决方案1】:

这就是我的实现方式

写入文件:

(defun my-write (file data)
  (with-temp-file file
    (prin1 data (current-buffer))))

从文件中读取:

(defun my-read (file symbol)
  (when (boundp symbol)
    (with-temp-buffer
      (insert-file-contents file)
      (goto-char (point-min))
      (set symbol (read (current-buffer))))))

打电话来写:

(my-write "~/test.txt" emacs-version)

打电话阅读

(my-read "~/test.txt" 'my-emacs-version)

【讨论】:

  • 您可以使用(goto-char (point-min)) 后跟(read (current-buffer)),这样您就不必创建字符串了。
  • @Lindydancer 已根据您的建议进行编辑。
  • 太棒了!但是,我建议将goto-char 放在insert-file-content 之后,这样会更容易阅读。此外,您是否有任何理由不返回读取值而不是设置变量?该代码将非常简单:(defun my-read-from-file (file) (with-temp-buffer (insert-file-content file) (goto-char (point-min)) (read (current-buffer))))
  • @Lindydancer 有问题with-temp-file 是由with-current-buffer 实现的,它是由save-current-buffer 实现的,它需要char-or-string-p 作为参数。如果没有转换为字符串,我有问题用hashtable 序列化cl-struct
  • 嗯? (read (current-buffer))(read (buffer-string)) 应该是等价的(如果 point 在缓冲区的开头),除了在后一种情况下,需要创建一个可能很大的字符串。您提到的with-temp-file 由 writer 函数使用,这是一个不同的问题。 (或者我错过了什么?)
【解决方案2】:

受第一个答案的启发,我想出了以下解决方案:

(with-temp-buffer
   (insert "(setq hash-table ")
   (prin1 hash-table (current-buffer)
   (insert ")")
   (write-file (locate-library "my-data-lib"))

在主模式的初始化过程中,我只是这样做:

(load "my-data-lib")

不需要和读取操作,而且我也不需要提供任何文件路径,只要加载路径上某处有这样的文件就足够了。 Emacs 会找到它。 省略岩石。 :)

【讨论】:

    【解决方案3】:

    desktop可以为你做:

    (require 'desktop)
    (unless (memq 'hash-table desktop-globals-to-save)
      (nconc desktop-globals-to-save (list 'hash-table)))` 
    

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 2011-10-05
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 2013-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多