TL;DR
F
Failures:
1) MyLib .major_version should be equal 1
Failure/Error: assert MyLib.major_version == 1
MyLib.major_version == 1
| | |
| | 1
| false
2
# ./spec/my_lib_spec.cr:6
やったぜ
power assert とは
ぐぐってくれ。
実装方法
Crystal には macro があって、大変めちゃカッコイイのだが、これをとにかく乱用して作り上げている。文字列生成周りがすごいハードコード感にあふれていて厳しいのでなんとかしたいのだが、うまくいく気がしない。
ちなみに、最初は Ruby の power-assert よろしく
assert { a == b }
という具合にとろうとしていたのだが、これだと macro 側で受ける時、
macro assert(&block)
と書くことになる。この block
にわたってくるのは Macros::Block なんだけど、 Macros::Block
からソースコードはとれても、その中身まで言及することが出来ない。ちなみに評価結果だけなら {{ block }}
って書いときゃもらえる。
で、とにかくそのままな AST をゲットするためにはどうすれバインダーとバインバインしていたら、素直に
macro assert(expression)
と書いておけば、 Macros::Call
なりが吹っ飛んでくることが判明。この時点でほぼ勝ち申した。
Macros::Call
Macros::Call には receiver
と args
と name
があるので、 power assert で出力を行う際に必要なものはほぼすべて手に入る。あとはこれをごちゃごちゃいじり回すだけなのだが、あんまりドキュメントが優しくないので少しむずかしい。気をつけよう。
a == b && c == d
に対応できない問題
既知の問題として assert a == b && c == d
を上手く取り扱うことが出来ない。ちなみにこれ、どういう AST が飛んでくるかというと Macros::If
が飛んでくる。なんでや!?と思ったら AST になる所で変形していて
if temp = (a == b)
c == d
end
という形で送っていますとのことでした。マジかよー。
うれしくないなぁと思いつつも、 assert に複雑な文を渡してる奴が悪いなこれは、ということであまり構わないことにしてリリースすることになりました。
今後の展望
Crystal の息が続く限り保守していくと思います。コンゴトモヨロシク。