Fix map-put and map-delete for alists (Bug#23105)
* lisp/emacs-lisp/map.el (map-put): Do not bind the evaluated place expression to a new symbol. * test/lisp/emacs-lisp/map-tests.el: Add a regression test.
This commit is contained in:
parent
422c3dadce
commit
3a13472ade
2 changed files with 18 additions and 27 deletions
|
@ -123,33 +123,26 @@ MAP can be a list, hash-table or array."
|
|||
default)))
|
||||
|
||||
(defmacro map-put (map key value)
|
||||
"Associate KEY with VALUE in MAP and return MAP.
|
||||
"Associate KEY with VALUE in MAP and return VALUE.
|
||||
If KEY is already present in MAP, replace the associated value
|
||||
with VALUE.
|
||||
|
||||
MAP can be a list, hash-table or array."
|
||||
(macroexp-let2 nil map map
|
||||
`(progn
|
||||
(setf (map-elt ,map ,key) ,value)
|
||||
,map)))
|
||||
`(setf (map-elt ,map ,key) ,value))
|
||||
|
||||
(defmacro map-delete (map key)
|
||||
(defun map-delete (map key)
|
||||
"Delete KEY from MAP and return MAP.
|
||||
No error is signaled if KEY is not a key of MAP. If MAP is an
|
||||
array, store nil at the index KEY.
|
||||
|
||||
MAP can be a list, hash-table or array."
|
||||
(declare (debug t))
|
||||
(gv-letplace (mgetter msetter) `(gv-delay-error ,map)
|
||||
(macroexp-let2 nil key key
|
||||
`(if (not (listp ,mgetter))
|
||||
(map--delete ,mgetter ,key)
|
||||
;; The alist case is special, since it can't be handled by the
|
||||
;; map--delete function.
|
||||
(setf (alist-get ,key (gv-synthetic-place ,mgetter ,msetter)
|
||||
nil t)
|
||||
nil)
|
||||
,mgetter))))
|
||||
(map--dispatch map
|
||||
:list (setf (alist-get key map nil t) nil)
|
||||
:hash-table (remhash key map)
|
||||
:array (and (>= key 0)
|
||||
(<= key (seq-length map))
|
||||
(aset map key nil)))
|
||||
map)
|
||||
|
||||
(defun map-nested-elt (map keys &optional default)
|
||||
"Traverse MAP using KEYS and return the looked up value or DEFAULT if nil.
|
||||
|
@ -337,15 +330,6 @@ MAP can be a list, hash-table or array."
|
|||
(cdr pair)))
|
||||
map))
|
||||
|
||||
(defun map--delete (map key)
|
||||
(map--dispatch map
|
||||
:list (error "No place to remove the mapping for %S" key)
|
||||
:hash-table (remhash key map)
|
||||
:array (and (>= key 0)
|
||||
(<= key (seq-length map))
|
||||
(aset map key nil)))
|
||||
map)
|
||||
|
||||
(defun map--apply-hash-table (function map)
|
||||
"Private function used to apply FUNCTION over MAP, MAP being a hash-table."
|
||||
(let (result)
|
||||
|
|
|
@ -87,9 +87,16 @@ Evaluate BODY for each created map.
|
|||
(let ((vec [3 4 5]))
|
||||
(should-error (setf (map-elt vec 3) 6))))
|
||||
|
||||
(ert-deftest test-map-put-alist-new-key ()
|
||||
"Regression test for Bug#23105."
|
||||
(let ((alist '((0 . a))))
|
||||
(map-put alist 2 'b)
|
||||
(should (eq (map-elt alist 2)
|
||||
'b))))
|
||||
|
||||
(ert-deftest test-map-put-return-value ()
|
||||
(let ((ht (make-hash-table)))
|
||||
(should (eq (map-put ht 'a 'hello) ht))))
|
||||
(should (eq (map-put ht 'a 'hello) 'hello))))
|
||||
|
||||
(ert-deftest test-map-delete ()
|
||||
(with-maps-do map
|
||||
|
|
Loading…
Add table
Reference in a new issue