Lispの属性リストとSymbolの調査(2)
id:smeghead:20070606:plist 前のエントリの続き
属性リストを関数に渡す方法は、symbol-plistでリストとして渡すしかないみたいでした。もしくはグローバルSymbolを参照するか。追記参照
emacs-lispには、setplistという関数で、Symbolに対して属性リストに一括で登録できるようですが、clispでは、setplistという関数はありませんでした。(clispでの一括設定は追記参照)
グローバルのシンボルの属性リストなら活用できる場面はあるかもしれませんが、あまり活用する場面は無いかもしれないというのが印象でした。普通にhash-tableを使うと思う。
追記20070611
コメント欄でNANRIさんに指摘頂いたように、関数にproperty listを渡せないというのは間違いでした。
Symbolを引数に取る関数
;関数にSymbolを渡す。 (defun print-plist (sym) (labels ((rec (lst) (if (null lst) nil (progn (format t "~a:~a~%" (first lst) (second lst)) (rec (cddr lst)))))) (rec (symbol-plist sym))))
gensym関数で生成したSymbolをprint-plistに渡す
(setf sym (gensym)) (setf (get sym 'prop1) "val1") (setf (get sym 'prop2) "val2") (print-plist sym)
‘でSymbol名を指定しただけのSymbolをprint-plistに渡す
(setf (get 'sym2 'prop3) "val3") (setf (get 'sym2 'prop4) "val4") (print-plist 'sym2)
上の2つのSymbolの生成方法の場合も共にSymbolを引数渡しして、関数内で引数のproperty listにアクセスすることができました。
呼び出し元でsymbol-plistでリストに変換してから引数に渡さないといけないと勘違いしたのは、引数の評価タイミングと評価された結果が何になるのかを理解していないだけでした。具体的には、(print-plist ‘sym2) を (print-plist sym2)としていた(‘を付けていなかった)ため、関数呼び出し時に、sym2が評価されvalueが関数に渡されることに気付かなかったためでした。
clispでのproperty listの一括設定
あともう一つ、clispではsetplist関数はないが、以下の方法でproperty listを一括設定できました。
(setf (symbol-plist sym) '(prop5 "val5" prop6 "val6"))
property listの注意
The use of setf should be avoided, since a symbol’s property list is a global resource that can contain information established and depended upon by unrelated programs in the same Lisp image.
http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_4.htm
シンボルのプロパティリストは、同じLispイメージにおける関係ないプログラムで作られたり依存している情報を含む可能性があるグローバル資源なので、上書き(setf)はお進めできないということのようです。
#なるべくlisp用語は英語で意識するようにした方が英語のドキュメントを読むときに楽だと思いました。(属性リスト → property list)
想像で書く前に仕様を参照しましょう。
(setf (symbol-plist ’sym) ’(a 1 b 2 c 3))
http://www.lispworks.com/documentation/HyperSpec/Body/f_symb_4.htm
NANRIさん、指摘ありがとうございます。
仰る通りでした。エントリの間違った情報は訂正していきます。理解に時間がかかるかもしれませんが。
Symbolについても http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm#symbol
からやりなおします。正しく理解できるように気を付けますが、またおかしな部分がありましたら、指摘おねがいしますm(_ _)m