Subject: bug#63513: closed (Re: bug#63513: [PATCH] Make persist-defvar work with records and hash tables)

From: [email-masked] (GNU bug Tracking System)
Date: Tue, 05 Sep 2023 21:08:02 +0000

Your bug report

#63513: [PATCH] Make persist-defvar work with records and hash tables

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
63513: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=63513
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#63513: [PATCH] Make persist-defvar work with records and hash tables
From: Stefan Monnier <[email-masked]>
To: Joseph Turner <[email-masked]>
Cc: Adam Porter <[email-masked]>, Eli Zaretskii <[email-masked]>, [email-masked], [email-masked]
Date: Tue, 05 Sep 2023 17:06:17 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

> Here you go!

Thanks, pushed!

        Stefan

Subject: [PATCH] Make persist-defvar work with records and hash tables
From: Joseph Turner <[email-masked]>
To: [email-masked]
Cc: Adam Porter <[email-masked]>
Date: Sun, 14 May 2023 22:56:20 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello!

persist-defvar does not persist records or hash tables correctly.

Here's a minimal example with a hash table:

(progn
  (persist-defvar foo (make-hash-table :test #'equal) "docstring")
  (puthash 'bar t foo)
  (persist-save 'foo)
  (gethash 'bar (persist-default 'foo))) ;; Expected nil, got t

This patch fixes persisting records by using copy-tree. Currently,
copy-tree does not work with records (see
<https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-05/msg00875.html>).
The following snippet will return the expected value only when both this
patch and the above-linked patch are applied:

(progn
  (cl-defstruct baz a)
  (persist-defvar quux (make-baz :a nil) "docstring")
  (setf (baz-a quux) t)
  (persist-save 'quux)
  (baz-a (persist-default 'quux))) ;; Expected nil, got t

Before applying this patch, the updated values in both cases are not
persisted to disk. With the patch, the updated values are persisted as
expected.

Best,

Joseph

>From b1512983fb82b9800ab6d0d1c9ca359e1251e94a Mon Sep 17 00:00:00 2001
From: Joseph Turner <[email-masked]>
Date: Sun, 14 May 2023 22:32:16 -0700
Subject: [PATCH] Make persist-defvar work with records and hash tables

Previously, when persist-defvar received a record or hash table for an
initial value, updated values were not persisted. This was because the
value and default value shared the same structure.
---
 persist.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/persist.el b/persist.el
index d80943d19e..a40fc2b297 100644
--- a/persist.el
+++ b/persist.el
@@ -118,7 +118,9 @@ (defun persist-symbol (symbol &optional initvalue)
   (let ((initvalue (or initvalue (symbol-value symbol))))
     (add-to-list 'persist--symbols symbol)
     (put symbol 'persist t)
-    (put symbol 'persist-default initvalue)))
+    (if (eq 'hash-table (type-of initvalue))
+        (put symbol 'persist-default (copy-hash-table initvalue))
+      (put symbol 'persist-default (copy-tree initvalue t)))))
 
 (defun persist--persistant-p (symbol)
   "Return non-nil if SYMBOL is a persistant variable."
-- 
2.40.1