Shammer's Philosophy

My private adversaria

コマンドライン引数をKeywordのように扱うには?その3

コマンドライン引数をKeywordのように扱うには?その2 - Shammerismの続きだ。前回は、完全に一組の引数しか意識していなかった。これを複数の引数に対応できるようにする。前回のコードを少し修正し以下のようになっている。

(defun main ()
  (let ((args (cdr (member "--" *command-line-argument-list* :test 'string-equal))))
    (format t "param is ~A, param type is ~A~%" args (type-of args))
    (let (new-list)
      (dolist (x args)
	(if (char= #\: (aref x 0))
	    (setf new-list
		  (append new-list (list (intern (subseq x 1) :keyword))))
	    (setf new-list
		  (append new-list (list x)))))
      (format t "new-list is ~A.~%" new-list)
      (format t "key is ~A." (getf new-list :key)))))

以前との変更点は、引数全体を dolist でチェックするようにしたこと、文字列の最初がコロンの場合は、コロンを一旦外して intern するようにしたことだ。dolist は何も特別なことはしていない。文字列の要素にアクセスするために aref を使用している。最初の一字にアクセスし、これがコロン付の場合は二文字目以降を intern の引数として渡す。そうしないと、見た目は sequence っぽいが、getf で値を引くことができない。これを実行すると以下のようになった。

$ ./test -- :KEY bbb
param is (:KEY bbb), param type is CONS
new-list is (KEY bbb).
key is bbb.
$

問題なく値を取得することに成功。