Elixir のテストの assert は引数が一つで、一つの式を与えるのですが、左辺と右辺のそれぞれの値を把握しています。
例えば。
適当なプロジェクトを作り、
$ mix new foo $ cd foo
テストをこんな風に書いて、
# test/foo_test.exs defmodule FooTest do use ExUnit.Case test "1 + 2 == 4 ...?" do assert 1 + 2 == 4 end end
テストを実行してみると、
$ mix test
1) test 1 + 2 == 4 ...? (FooTest)
test/foo_test.exs:4
Assertion with == failed
code: assert 1 + 2 == 4
left: 3
right: 4
stacktrace:
test/foo_test.exs:5: (test)
Finished in 0.02 seconds
1 test, 1 failure
こんな感じになります。
Elixir の assert はマクロで記述されていて、引数を評価前の式の構造のままで受け取ることで実現しているようです。
おもしろい…と思っていたのだけれど、似たようなことが Prolog でも書けることに気がつきました。
% foo_test.prolog judge(L, L) :- format("OK", []), !. judge(L, R) :- format("failed~n left: ~d~n right: ~d~n", [L, R]). assert(LHS == RHS) :- L is LHS, R is RHS, judge(L, R).
$ gprolog GNU Prolog 1.4.4 (64 bits) | ?- ['foo_test.prolog']. | ?- assert(1 + 2 == 4). failed left: 3 right: 4 yes
述語 assert は引数に LHS == RHS という構造の式を受け取ります。Prolog では引数として式を書くと評価されずに式のまま述語に渡されます。受け取る側では式の形でマッチさせることで右辺と左辺を取り出すことができるわけです。
以前にも評価されるまで式の形のままで受け渡しができることを利用した Key-Value ペアを扱う方法について書きましたので、興味がある方はどうぞ。