by shigemk2

当面は技術的なことしか書かない

値による場合分け

caseとかtypetestとか使うといいんだよねー

(defun case-test (value)
  (case value
    (1 "one")
    ((2 3) "two or three")
    ((t) "true")
    (t "other")))
(case-test 1)				; => "one"
(case-test 3)				; => "two or three"
(case-test t)				; => "true"
(case-test 9)				; => "other"

(defun type-test (v)
  (typecase v
    (null "nil")
    (character "1-4194303の整数")	; 別名string-char
    ;; number(別名real)は数値全体
    (integer "整数")			; 別名fixnum
    (float "浮動小数点数")
    (string "文字列")
    (list "リスト")
    (vector "ベクタ")
    (hash-table "ハッシュテーブル")
    (buffer "バッファ")
    (window "ウィンドウ")
    (t "それ以外")))
(type-test nil)				; => "nil"
(type-test 3)				; => "1-4194303の整数"
(type-test ?a)				; => "1-4194303の整数"
(type-test 4194304)			; => "整数"
(type-test 1.1)				; => "浮動小数点数"
(type-test "foo")			; => "文字列"
(type-test '(1 2))			; => "リスト"
(type-test '(1 . 2))			; => "リスト"
(type-test [1])				; => "ベクタ"
(type-test (make-hash-table))		; => "ハッシュテーブル"
(type-test (current-buffer))		; => "バッファ"
(type-test (selected-window))		; => "ウィンドウ"
(type-test (selected-frame))		; => "それ以外"

(defun range-test (v)
  (typecase v
    (zero "0")
    ;; 数値でx以上y以下を指定できる
    ((integer 1 5) "1-5の整数")
    ((number 1 5) "1-5の数値")
    ((float 10 50) "10-50の浮動小数点数")
    ((member 10 20) "10または20")
    ;; 上限下限がないときは*を指定する
    ((number * 0) "負の数")
    ((number 0 *) "正の数")))
(range-test 0)				; => "0"
(range-test 3)				; => "1-5の整数"
(range-test 2.2)			; => "1-5の数値"
(range-test 20.0)			; => "10-50の浮動小数点数"
(range-test 20)				; => "10または20"
(range-test 200)			; => "正の数"
(range-test -20)			; => "負の数"

(defun complex-type-test (v)
  (typecase v
    ((and integer (number 5.3 8.2)) "5.3-8.2の間の整数")
    ((or integer (float 0 *)) "整数または非負の浮動小数点数")))
(complex-type-test 6)			; => "5.3-8.2の間の整数"
(complex-type-test 99.0)		; => "整数または非負の浮動小数点数"
(complex-type-test -2)			; => "整数または非負の浮動小数点数"

P204

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル