Next: 組み合わせ条件の構築, Previous: 順序, Up: 制御構造 [Contents][Index]
条件による制御構造は候補の中から選択を行ないます。Emacs
Lispは5つの条件フォームをもちます。ifは他の言語のものとほとんど同じです。whenとunlessはifの変種です。condは一般化されたcase命令です。condを汎用化したものがpcaseです(パターンマッチングによる条件を参照)。
ifはconditionの値にもとづきthen-formとelse-formsを選択する。評価されたconditionが非nilならthen-formが評価されて結果がリターンされる。それ以外ならelse-formsがテキスト順に評価されて最後のフォームの値がリターンされる(ifのelseパートは暗黙のprognの例である。順序を参照)。
conditionの値がnilでelse-formsが与えられなければ、ifはnilをリターンする。
選択されなかったブランチは決して評価されない — 無視される —
ので、ifはスペシャルフォームである。したがって以下の例ではprintが呼び出されることはないのでtrueはプリントされない。
(if nil
(print 'true)
'very-false)
⇒ very-false
これはelse-formsがなく、複数のthen-formsが可能なifの変種である。特に、
(when condition a b c)
は以下と完全に等価である
(if condition (progn a b c) nil)
これはthen-formがないifの変種です:
(unless condition a b c)
は以下と完全に等価である
(if condition nil a b c)
condは任意個数の選択肢から選択を行なう。cond内の各clauseはリストでなければならない。このリストのCARはconditionで、(もしあれば)残りの要素はbody-formsとなる。したがってclauseは以下のようになる:
(condition body-forms…)
condは各clauseのconditionを評価することにより、テキスト順でclauseを試みる。conditionの値が非nilならそのclauseは成り立つ。その後にcondはそのclauseのbody-formsを評価して、body-formsの最後の値をリターンする。残りのclauseは無視される。
conditionの値がnilならそのclauseは失敗して、condは次のclauseに移動してそれのconditionを試みる。
clauseは以下のようにも見えるかもしれない:
(condition)
conditionがテストされたときに非nilなら、condフォームはconditionの値をリターンする。
すべてのconditionがnilに評価された場合 —
つまりすべてのclauseが不成立なら、condはnilをリターンする。
以下の例はxの値が数字、文字列、バッファー、シンボルなのかをテストする4つのclauseをもつ:
(cond ((numberp x) x)
((stringp x) x)
((bufferp x)
(setq temporary-hack x) ; 1つのclauseに
(buffer-name x)) ; 複数bodyフォーム
((symbolp x) (symbol-value x)))
前のclauseが不成立のとき最後の条項を実行したいときがよくある。これを行なうには(t
body-forms)のように、conditionの最後のclauseにtを使用する。フォームtはtに評価され決してnilにならないので、このclauseが不成立になることはなく最終的にcondはこのclauseに到達する。たとえば:
(setq a 5)
(cond ((eq a 'hack) 'foo)
(t "default"))
⇒ "default"
このcond式はaの値がhackならfoo、それ以外は文字列"default"をリターンする。
すべての条件構文はcondかifのいずれかで表すことができます。したがってどちらを選択するかはスタイルの問題になります。たとえば:
(if a b c) ≡ (cond (a b) (t c))