コマンドライン引数をKeywordのように扱うには?その1
&KEY をちょっとだけ使用してみようと思う - Shammerismで、コマンドライン引数をKeywordのように扱うことができないか、というように考えて結局やらずじまいだったが。ちょっといろいろおさらいしつつやってみる。
まず、対象は ClozureCL で、コマンドライン引数を扱うには *command-line-argument-list* を使用する。スクリプトとして動作させるなら、*unprocessed-command-line-arguments* でもよいが、*unprocessed-command-line-arguments* の場合は引数は -- 以降のものになる。まあ、これに合わせて、*command-line-argument-list* でも -- 以降が引数として扱われるようにしてみたい。こうすればいいだけ。
(let ((x (cdr (member "--" *command-line-argument-list* :test 'string-equal)))) ...
この場合、x に -- 以降の文字列が格納される。単純に以下のようにするとどういう状態で取得されるかがわかる。
(defun main () (let ((x (cdr (member "--" *command-line-argument-list* :test 'string-equal)))) (format t "param is ~A, param type is ~A~%" x (type-of x))))
これを
(save-application "test" :toplevel-function #'main :prepend-kernel t)
でコンパイルして、./test -- aaa xxx とかやると以下のようになる。
$ ./test -- aaa xxx param is (aaa xxx), param type is CONS $
ここでは普通に aaa と xxx は文字列として扱われている。これを :key value というような引数を渡すことで、キーワードとして使用されるようにしたい。
$ ./test -- :key value param is (:key value), param type is CONS $
とりあえずはよさげ。本当にキーワードになっているか。キーワードなら、(getf x :key) で value を取得できるはず。そこで、main を以下のように変更する。
(defun main () (let ((x (cdr (member "--" *command-line-argument-list* :test 'string-equal)))) (format t "param is ~A, param type is ~A~%" x (type-of x)) (format t "key is ~A." (getf x :key))))
そして、これを再度コンパイルして ./test -- :key value を実行。その結果が以下。
$ ./test -- :key value param is (:key value), param type is CONS key is NIL. $
値を取得できていない。。。:key が渡されていても、Keyword 引数としてではなく単純な文字列として扱われてしまっている、ということと思われる。これを解消するには、:keyword 引数を付与して intern をしてやる、というのでどうか。これはまた今度やってみよう。