Previous: , Up: Lisp Data Types   [Contents][Index]


2.7 同等性のための述語

ここでは2つのオブジェクトの同一性をテストする関数を説明します。(たとえば文字列などの)特定の型のオブジェクト同士で内容の同一性をテストするのは、別の関数を使用します。これらの述語にたいしては、そのデータ型を説明する適切なチャプターを参照してください。

Function: eq object1 object2

この関数はobject1object2が同じオブジェクトならt、それ以外はnilをリターンする。

object1object2が同じ値をもつ整数なら、これらは同じオブジェクトと判断される(eqtをリターンする)。object1object2が同じ名前のシンボルなら、通常は同じオブジェクトであるが例外もある。Creating Symbolsを参照のこと。(リストやベクター、文字列などの)他の型にたいしては、同じ内容(または要素)の2つの引数が両者eqである必要はない。これらが同じオブジェクトの場合だけeqであり、その場合は一方の内容を変更するともう一方の内容にも同じ変更が反映される。

(eq 'foo 'foo)
     ⇒ t

(eq 456 456)
     ⇒ t

(eq "asdf" "asdf")
     ⇒ nil

(eq "" "")
     ⇒ t
;; この例外は省スペースのためにEmacs Lispが
;; マルチバイトの空文字列を1つだけ作成するため

(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(setq foo '(1 (2 (3))))
     ⇒ (1 (2 (3)))
(eq foo foo)
     ⇒ t
(eq foo '(1 (2 (3))))
     ⇒ nil

(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(eq (point-marker) (point-marker))
     ⇒ nil

make-symbol関数はinternされていないシンボルをリターンする。これはLisp式内でその名前を記述したシンボルとは区別される。同じ名前の異なるシンボルはeqではない。Creating Symbolsを参照のこと。

(eq (make-symbol "foo") 'foo)
     ⇒ nil

Emacs Lispバイトコンパイラーはリテラル文字列のような等価なリテラルオブジェクトを同一オブジェクトにたいする参照に落し込む(collapse into)かもしれない。バイトコンパイルされたコードはそのようなオブジェクトをeqで比較するだろうが、そうでないコードは異なるという効果がある。したがってコードではオブジェクトのリテラルコンテンツがeqか否かではなく、以下に説明するequalのような関数でオブジェクトの関数を使用すること。同様にコードではリテラルオブジェクトを変更(たとえばリテラル文字列へのテキストプロパティのput)しないこと。バイトコンパイラーがそれらの落し込みを行っていたら、同一コンテンツをもつ別のリテラルオブジェクトに影響があるかもしれない。

Function: equal object1 object2

この関数はobject1object2が同じ構成要素をもつならt、それ以外はnilをリターンする。eqが引数が同じオブジェクトなのかテストするのにたいして、equalは同一でない引数の内部を調べて、それらの要素または内容が同一化をテストする。したがって2つのオブジェクトがeqならばそれらはequalだが、その逆は常に真ではない。

(equal 'foo 'foo)
     ⇒ t

(equal 456 456)
     ⇒ t

(equal "asdf" "asdf")
     ⇒ t
(eq "asdf" "asdf")
     ⇒ nil

(equal '(1 (2 (3))) '(1 (2 (3))))
     ⇒ t
(eq '(1 (2 (3))) '(1 (2 (3))))
     ⇒ nil

(equal [(1 2) 3] [(1 2) 3])
     ⇒ t
(eq [(1 2) 3] [(1 2) 3])
     ⇒ nil

(equal (point-marker) (point-marker))
     ⇒ t

(eq (point-marker) (point-marker))
     ⇒ nil

文字列の比較はcaseを区別するがテキストプロパティーは考慮しない — これは文字列内の文字だけを比較する。Text Propertiesを参照のこと。テキストプロパティーも比較する場合には、equal-including-propertiesを使用すること。技術的な理由によりユニバイト文字列とマルチバイト文字列は、それらが同じ文字コードのシーケンスを含み、それらのコードがすべて0から127(ASCII)の場合に限りequalとなる(Text Representationsを参照)。

(equal "asdf" "ASDF")
     ⇒ nil

しかし2つの別のバッファーは、それらのテキスト内容が同じでもequalと判断されることはない。

equalのテストは再帰的に実装されています。たとえば2つのコンスセルxyを与えると、(equal x y)は、以下の式の両方がtをリターンする場合だけtをリターンします:

(equal (car x) (car y))
(equal (cdr x) (cdr y))

これは再帰処理なので循環するリストがあると無限再帰となる(エラーとなる)。

Function: equal-including-properties object1 object2

この関数はすべてのケースにおいてequalと同様に振る舞うが、2つの文字列がequalになるためには、それらが同じテキストプロパティーをもつ必要がある。

(equal "asdf" (propertize "asdf" 'asdf t))
     ⇒ t
(equal-including-properties "asdf"
                            (propertize "asdf" 'asdf t))
     ⇒ nil

Previous: , Up: Lisp Data Types   [Contents][Index]