Common LIspの拡張関数defun*を使うと、
&optional デフォルト引数
&key キーワード引数
リスト分解機能
が使えるようになる。
;; 拡張されたデフォルト値 (defun* test-default (a &optional (b 2) (c 3 c-avail)) (list a b c c-avail)) (test-default 1) ; => (1 2 3 nil) (test-default 1 5) ; => (1 5 3 nil) (test-default 1 5 7) ; => (1 5 7 t) ;; キーワード引数 (defun* test-keyword (&key a (b 2)) (list a b)) (test-keyword) ; => (nil 2) (test-keyword :a 3) ; => (3 2) (test-keyword :a 3 :b 5) ; => (3 5) ;; 他のキーワードを指定したらエラーになる (ignore-errors (test-keyword :a 3 :b 5 :c 7)) ; => nil ;; 他のキーワードも受けつけるようにする ;; &allow-other-keysを使う (defun* test-other-keyword (&rest args &key a &allow-other-keys) (list args a (plist-get args :y))) (test-other-keyword :a 2) ; => ((:a 2) 2 nil) (test-other-keyword :x 0 :y 1) ; => ((:x 0 :y 1) nil 1) (test-other-keyword 1 2 3) ; => ((1 2 3) nil nil) ;; 省略可能引数とキーワード引数 (defun* test-many-args (a &optional b &key c) (list a b c)) (test-many-args 1) ; => (1 nil nil) (test-many-args 1 2) ; => (1 2 nil) (test-many-args 1 2 :c 3) ; => (1 2 3) ;; これはエラー (ignore-errors (test-many-args 1 2 3)) ; => nil ;; リスト分解機能 (defun* test-destructure (a (b c (d)) e) (list a b c d e)) (test-destructure 1 '(2 3 (4)) 5) ; => (1 2 3 4 5) ;; 複数の関数を使ってキーワード引数を解析する例 (defun* outer (&rest args &key a &allow-other-keys) (princ (format "a=%s " a)) ;; 残りのキーワード引数の解析をinnerに任せる (apply 'inner :allow-other-keys t args)) (defun* inner (&rest args &key b) (princ (format "b=%s" b))) (with-output-to-string (outer 8 :a 1 :b 2 :c 3)) ; => "a=1 b=2"
P193
- 作者: るびきち
- 出版社/メーカー: 技術評論社
- 発売日: 2011/11/26
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 220回
- この商品を含むブログを見る