Crystalでnopasteを作ってみました

nopasteのCrystal実装がなかったので作ってみました。

kozakana/crystal-nopaste

データベースは増やせるように作ってありますが、とりあえずsqlite3だけで作っています。

フレームワークはKemalを使用して、テンプレートエンジンはecrというerbのようなものを使用しています。

データベースへのアクセスだったり、ファイルへのアクセス後の型(Nilなど)の対応などに苦戦しました。

速度

文字を貼り付けて送信して表示という一連の操作のログ(3回分)が↓です。 (測った環境は[MacBookPro 2018/ 2.7 GHz Intel Core i7 / 16 GB 2133 MHz LPDDR3]ですが、環境整えたり比較したりしてちゃんと測ったわけではないので参考程度に)

releaseビルドして実行しています。

GET /以外はデータベースへのアクセスがあるのですがそれでも1ms程度と早く、データベースへのアクセスがないGET /に関しては数十µsとかなり早そうでした。

2019-02-23 21:01:19 +09:00 200 GET / 69.0µs
2019-02-23 21:01:24 +09:00 302 POST / 1.86ms
2019-02-23 21:01:24 +09:00 200 GET /Z60SAT67jaZKnK99DP5D6w 1.33ms

2019-02-23 21:01:25 +09:00 200 GET / 10.0µs
2019-02-23 21:01:27 +09:00 302 POST / 1.56ms
2019-02-23 21:01:27 +09:00 200 GET /1LCAGQzv7KOhsPMxySWHNw 1.24ms

2019-02-23 21:01:28 +09:00 200 GET / 8.0µs
2019-02-23 21:01:30 +09:00 302 POST / 1.46ms
2019-02-23 21:01:30 +09:00 200 GET /OVK9CR6i5dA5fVnj4FyaXA 982.0µs

Kemalについて

Sinatraに似ているのでSinatraのようなFWを触ったことがあればすぐ使えると思います。それよりもCrystal独特な部分で苦労することが多いと思います。

ecrの使い方

ecrの使い方はerbとほとんど同じですが、インスタンス変数に入れたりなどしなくても、下記のように変数に入れるだけで使えます。

# controller
value = "abc"
render "src/views/show.ecr"
# view
<p><%= value %></p>

Crystalについて

今回Crystalで作ってみてCrystalはRubyとは一見似ているが、似て非なるものだということがわかりました。 Crystalはmacroを多様しているので実行時に動的に処理を変えるというのが難しいので、特にメタプログラミングのようなのはかなり難しいと思います。

ただ、簡単なアプリケーションですが作ってみて型推論周りがかなり勉強になりました。