Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2010-01-01

KMRCLを眺める (55) UPDATE-PLIST

| 00:37 | KMRCLを眺める (55) UPDATE-PLIST - わだばLisperになる を含むブックマーク はてなブックマーク - KMRCLを眺める (55) UPDATE-PLIST - わだばLisperになる

今回は、KMRCLのlists.lisp中からUPDATE-PLISTです。

以前のUPDATE-ALISTと同じくPLISTの内容を変更するユーティリティです。

定義は、

(defmacro update-plist (pkey value plist &key (test '#'eql))
  "Macro to support below (setf get-alist)"
  (let ((pos (gensym)))
    `(let ((,pos (member ,pkey ,plist :test ,test)))
       (if ,pos
           (progn
             (setf (cadr ,pos) ,value)
             ,plist)
         (setf ,plist (append ,plist (list ,pkey ,value)))))))

となっていて、これもUPDATE-ALISTと同じくマクロじゃなくて良い気がしますが、マクロになっています。

更新にはMEMBERで返ってきた値をつかうのですが、これだと、

(DEFPARAMETER *PLIST* (LIST :A 1 :B 2 :C 3 :D 4))

(UPDATE-PLIST 1 :FOO! *PLIST*)

*PLIST*
;⇒ (:A 1 :FOO! 2 :C 3 :D 4)

値の部分もキーとみなされてその次が更新されてしまうことになります…。

ということで良い機会なので自分も試しに作ってみました。

マクロではなくて関数にしています。

(DEFUN MY-UPDATE-PLIST (PKEY VALUE PLIST &KEY (TEST #'EQL))
  (IF (ENDP PLIST)
      (LIST PKEY VALUE)
      (DO ((PL PLIST (CDDR PL))
           (TAIL NIL PL)
           (MODIFYP NIL))
          ((ENDP PL) (PROG1 PLIST
                            (UNLESS MODIFYP 
                              (NCONC TAIL (LIST PKEY VALUE)))))
        (WHEN (FUNCALL TEST PKEY (CAR PL))
          (SETF (CADR PL) VALUE
                MODIFYP 'T)))))

UPDATE-PLISTはドキュメントストリングにも"Macro to support below (setf get-alist)"とタイポがあったり(そして、その(setf get-plistは存在しない…))で、なんとなくなげやりに作られたように思えます('-'*)