Common Lisp remf индикатор из plist не работает - PullRequest
1 голос
/ 11 ноября 2019

У меня есть функция с именем use, которая принимает произвольное количество аргументов ключевого слова (в виде списка), определенных следующим образом:

(defun use (&rest plist &key &allow-other-keys)
  ":href should be supplied, as it is the path/to/svg#id to be used."
  ;; Hole die Sachen die wichtig sind aus der PListe
    (let ((href (getf plist :href "#")))
      ;; Remove :href otherwise it appears in the plist again!
      (remf-indicators-from-plist '(:href) plist)
      (list plist href)
    ))

Здесь я извлекаю некоторые ключевые аргументы, которые важны и должны быть указаныпользователем, а затем удалите их из списка предоставленных аргументов ключевого слова с remf-indicators-from-plist, чтобы я не обработал их дважды. remf-indicators-from-plist определено ниже:

(defun remf-indicators-from-plist (indicators plist)
  "Removes indicators from the plist, 
to prevent callers from double-using them."
  (dolist (indicator indicators plist)
    (remf plist indicator)))

Теперь мне кажется, что ключевое слово аргумент / si хочет извлечь в функции use и затем удалить, действительно удаляются, если они появляются не как первыепараметр функции:

(use :x 34 :href 23 :c2 32)     ;((:X 34 :C2 32) 23)
(use :x 34 :c2 32 :href 23)     ;((:X 34 :C2 32) 23)

, но не в том случае, если он отображается в качестве первого параметра:

(use :href 23 :x 34 :c2 32)     ;((:HREF 23 :X 34 :C2 32) 23)

Почему это так? И как я могу это правильно реализовать?

1 Ответ

2 голосов
/ 11 ноября 2019

Проблема в функции use, в то время как remf-indicators-from-plist работает правильно.

Причина в том, что функция remf-indicators-from-plist возвращает измененный список (внутри dolist), но значениевозвращенный сбрасывается внутри use. Возможное решение состоит в том, чтобы изменить определение use, например, следующим образом:

CL-USER> (defun use (&rest plist &key &allow-other-keys)
            ":href should be supplied, as it is the path/to/svg#id to be used."
            ;; Hole die Sachen die wichtig sind aus der PListe
          (let ((href (getf plist :href "#"))
                (new-plist (remf-indicators-from-plist '(:href) plist)))
            (list new-plist href)))
USE
CL-USER> (use :x 34 :href 23 :c2 32)  
((:X 34 :C2 32) 23)
CL-USER> (use :href 23 :x 34 :c2 32) 
((:X 34 :C2 32) 23)

Тот факт, что когда :href находится внутри списка, все, очевидно, работает, из-за особого способа побочных эффектов. выполняется определенными операциями в Common Lisp. Правило, которое помогает в управлении побочными действиями (частично из-за того, что постоянные данные никогда не должны изменяться) состоит в следующем: всегда возвращает измененную структуру, даже если кажется, что изменения происходят «на месте».

...