1. rosylilly

    No comment

    rosylilly
Changes in body
Source | HTML | Preview
@@ -1,74 +1,74 @@
# TL;DR
https://github.com/rosylilly/power_assert.cr
```
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 よろしく
```rb
assert { a == b }
```
という具合にとろうとしていたのだが、これだと macro 側で受ける時、
```
macro assert(&block)
```
-と書くことになるのだが、この `block` にわたってくるのは [Macros::Block](http://crystal-lang.org/api/Macros/Block.html) になっているのだが、 `Macros::Block` からソースコードはとれても、その中身まで言及することが出来ない。ちなみに評価結果だけなら `{{ block }}` って書いときゃもらえる。
+と書くことになるこの `block` にわたってくるのは [Macros::Block](http://crystal-lang.org/api/Macros/Block.html) なんだけど、 `Macros::Block` からソースコードはとれても、その中身まで言及することが出来ない。ちなみに評価結果だけなら `{{ block }}` って書いときゃもらえる。
で、とにかくそのままな AST をゲットするためにはどうすれバインダーとバインバインしていたら、素直に
```
macro assert(expression)
```
と書いておけば、 `Macros::Call` なりが吹っ飛んでくることが判明。この時点でほぼ勝ち申した。
## Macros::Call
[Macros::Call](http://crystal-lang.org/api/Macros/Call.html) には `receiver` と `args` と `name` があるので、 power assert で出力を行う際に必要なものはほぼすべて手に入る。あとはこれをごちゃごちゃいじり回すだけなのだが、あんまりドキュメントが優しくないので少しむずかしい。気をつけよう。
## `a == b && c == d` に対応できない問題
既知の問題として `assert a == b && c == d` を上手く取り扱うことが出来ない。ちなみにこれ、どういう AST が飛んでくるかというと `Macros::If` が飛んでくる。なんでや!?と思ったら AST になる所で変形していて
```crystal
if temp = (a == b)
c == d
end
```
という形で送っていますとのことでした。マジかよー。
うれしくないなぁと思いつつも、 assert に複雑な文を渡してる奴が悪いなこれは、ということであまり構わないことにしてリリースすることになりました。
## 今後の展望
Crystal の息が続く限り保守していくと思います。コンゴトモヨロシク。