12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

power_assert.cr 作った

Last updated at Posted at 2015-06-25

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 には receiverargsname があるので、 power assert で出力を行う際に必要なものはほぼすべて手に入る。あとはこれをごちゃごちゃいじり回すだけなのだが、あんまりドキュメントが優しくないので少しむずかしい。気をつけよう。

a == b && c == d に対応できない問題

既知の問題として assert a == b && c == d を上手く取り扱うことが出来ない。ちなみにこれ、どういう AST が飛んでくるかというと Macros::If が飛んでくる。なんでや!?と思ったら AST になる所で変形していて

if temp = (a == b)
  c == d
end

という形で送っていますとのことでした。マジかよー。

うれしくないなぁと思いつつも、 assert に複雑な文を渡してる奴が悪いなこれは、ということであまり構わないことにしてリリースすることになりました。

今後の展望

Crystal の息が続く限り保守していくと思います。コンゴトモヨロシク。

12
12
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?