Crystal でのプログラミングを支援するツール達

この記事は Crystal Advent Calendar 2015 の13日目の記事です.

Ruby の構文が好きなので Crystal もぼちぼち触っていて,標準ライブラリに Random::MT19937 とか Array#transpose を実装したり,Lisp 実装してみたりコマンドラインからドキュメント開くやつつくったりしています.

また,Vim 上で Crystal のコードを書くために vim-crystal というファイルタイププラグインをつくっていて,これから紹介するいくつかのツールも統合されています.

Crystal はつくりかけの言語であり,まだまだ言語機能的にも変更があったり足りないところがあったりしますが,つくりかけながらもプラグラミングをサポートする機能やツールがいくつかあります.今回はそれらを紹介します.

紹介するツール

Crystal Tool

Crystal Tool は Crystal コンパイラが公式にサポートしているツール群です.コンパイラの一部として実装されているので,下記のコマンドで概要が表示されます.

$ crystal tool

実装者は implementationscontext@bcardiff さん,それ以外は @asterite さんです.

format

crystal tool format はコードを整形するフォーマッタです.Crystal で推奨されているコードスタイルでコードを整形できます.最初は公式でフォーマッタが実装される予定は無かったのですが,方針が変わり 0.9.0 で実装されました.

引数を何も指定しないとカレントディレクトリ下の Crystal コードを,ディレクトリを指定するとそのディレクトリ下の Crystal コードを,ファイルを指定するとそのファイルをそれぞれ整形します.

~/Dev/github.com/rhysd/Crisp % crystal tool format
Format ./foo.cr
Format ./spec/helper.cr
Format ./src/crisp/core.cr
Format ./src/crisp/env.cr
Format ./src/crisp/error.cr
Format ./src/crisp/evaluator.cr
Format ./src/crisp/expr.cr
Format ./src/crisp/interpreter.cr
Format ./src/crisp/printer.cr
Format ./src/crisp/reader.cr

どんな感じで整形されるのかは,試しに自分のプロジェクトに整形をかけてみた diff を gist に貼ったので,そちらを見てみてください.

Go 言語の gofmt のように,Crystal のコードを書く時はこれでコードを整形することが推奨されています.vim-crystal では Vim のコマンドで直接カレントバッファを整形したり,保存時に整形したりできます.

implementations, context

crystal tool implementations は,メソッド呼び出しから呼び出し元がどこで定義されているかを解析します.

また,crystal tool context は Crystal コードの特定の箇所におけるコンテキスト(式や変数およびその型)を表示してくれます.

Open Class などの機能がある Crystal ではコード全体を見ないと特定箇所のコンテキストが定まらないので,これらのツールはプロジェクト全体のファイルをターゲットとして実行する必要があります.また,-c でファイル内の位置を指定する必要があります.出力は -f で指定でき,人間に優しい text フォーマットとプログラムに優しい json フォーマットが選べます. ユーザが直接使うものというよりは Crystal 用のツールやエディタプラグインが使うもので,atom-crystal-tools, vim-crystal では既にサポートされています.

Crystal は型推論やテンプレートを使って極力型を書かなくて良いようになっているので,こういったツールで式が実際にどのような型になっているのかや,どこのどのメソッドを呼び出しているのかなどを確認できます.

手前味噌ですが,vim-crystal ではこのようにカーソル下の呼び出し元にジャンプしたり,カーソル下のコンテキストが表示できたりします.

screenshort screenshot

hierarchy

crystal tool hierarchy は,指定したファイルのクラス階層を表示してくれるツールです.これによって,実際にメソッドのテンプレートがどのようなメソッドを生成しているかや,ジェネリックなクラスがどのようなクラス (struct) を生成しているかを見ることができます.Crystal のコードを書いている時だけでなく,Crystal コンパイラ本体のデバッグをしている時にも便利です.

試しに手元のプロジェクトで crystal tool hierarchy を実行してみた 出力結果を gist に貼ってみました

なお,vim-crystal では :CrystalHierarchy でカレントバッファに対して直接実行できます.

crdoc

github.com

crdocコマンドラインから Crystal のドキュメントを開くためのコマンドラインツールで,Crystal で書かれています.

Crystal は元々ドキュメントサーバを立ててブラウザからドキュメントを見られる仕組みがあるのですが,コマンドライン内でコードを書いているときはシェルから直接ドキュメントを開けると良いなと思いつくりました.

main usage

release ページ から落としてきたバイナリなり,ビルドしたバイナリなりを PATH の通ったディレクトリに置くとすぐ使えます.初回時にキャッシュを生成するためにリポジトリを clone してくるので,少しだけ時間がかかります.

基本的には crdoc search 検索ワード で検索し,複数の候補が見つかった場合は選択肢が表示されますので,番号で指定すると対応するドキュメントが開きます.

また,pecopercol のようなフィルタリングツールも意識していて,例えば OS X だと下記のようなコマンドでドキュメントをインタラクティブに絞り込んで選択できます.

$ open "$(crdoc list --path | peco)"
$ open "$(crdoc list --path | percol)"

peco example

この他にも rake の Crystal 版である crake など,色々なツールが Crystal で書かれています.

Playground

最近の多くの言語にあるように,実は Crystal にもブラウザ上で言語を試せる Playground があります.Crystal collaborator の @jhass さん作です.

carc.in

常にリリースされた最新の Crystal が利用できるようになっており,バグ報告やコードの共有などで使われています. Crystal は LinuxOS X では簡単にインストールできますが,それ以外の対応できていないプラットフォームでは playground で Crystal を試すことが出来ます.

f:id:rhysd:20151212182246p:plain

まとめ

Crystal のコードを書く上で便利なツールを紹介しました.これ以外にも依存管理をやってくれる shards など便利なツールがたくさんあるので,ガンガン活用していきたいです.