Crystalのcli紹介 "tool context"
この記事は、 Crystal Advent Calendar 2017 の15日目の記事です。
crystalのcliには便利なサブコマンドやオプションがあります。コーディングを支えるものだったり、build時の細かな設定だったりします。知っていると得をする、だけど知らない人も多いかもしれない。そんなサブコマンドやオプションを紹介します。
今回は、 $ crystal tool context
を紹介します。
tool context
まずはcliのhelpを見てみましょう。
$ crystal tool --help Usage: crystal tool [tool] [switches] [program file] [--] [arguments] Tool: context show context for given location expand show macro expansion for given location format format project, directories and/or files hierarchy show type hierarchy implementations show implementations for given call in location types show type of main variables --help, -h show this help
context
があります。
show context for given location
現在位置のスコープの情報を出力してくれるコマンドです。context
のhelpも見てみましょう。
$ crystal tool context --help Usage: crystal tool context [options] [programfile] [--] [arguments] Options: -D FLAG, --define FLAG Define a compile-time flag -c LOC, --cursor LOC Cursor location with LOC as path/to/file.cr:line:column -f text|json, --format text|json Output format text (default) or json --error-trace Show full error trace -h, --help Show this message --no-color Disable colored output --prelude Use given file as prelude -s, --stats Enable statistics output -p, --progress Enable progress output -t, --time Enable execution time output
よく使うのは-c
オプションです。カーソルの位置をファイルパス:行数:列数
と指定することで、その位置のスコープ情報を出力してくれます。
例を見てみましょう。下記のファイルを用意します。
src/context.cr
module Context class MyClass def initialize(@iv1 : String, @iv2 : String) @iv3 = [@iv1, @iv2] # cursor1 end def my_method lv1 = 1 lv2 = 1.1 lv3 = [1, 2] lv4 = [lv1, lv2, lv3, @iv3] # cursor2 lv4 end end end c = Context::MyClass.new("hoge", "fuga") p c.my_method
コマンドを打ってみます。5:7
は# cursor1
の部分です。
$ crystal tool context -c src/context.cr:5:7 src/context.cr 1 possible context found | Expr | Type | --------------------------- | self | Context::MyClass | | @iv1 | String | | @iv2 | String | | @iv3 | Array(String) | | iv1 | String | | iv2 | String |
このスコープにある変数一覧と型が表示されました。ここでふと気づくのが、iv1
とiv2
があることです。コード上では存在していません。
実は、@iv1
や@iv2
に直接代入する構文、
def initialize(@iv1 : String, @iv2 : String)
ここでは一度local変数に代入されているのです。試しにローカル変数を表示してみましょう。
... def initialize(@iv1 : String, @iv2 : String) @iv3 = [@iv1, @iv2] p iv1 # cursor1 end ...
出力は以下です。
$ crystal run src/context.cr "hoge" [1, 1.1, [1, 2], ["hoge", "fuga"]]
hoge
が出力されているので、ローカル変数iv1
が存在していることになります。context
を見てみることで、このような気付きを得ることができました。
ちなみに# cursor2
の位置でcontext
を実行すると以下になります。
$ crystal tool context -c src/context.cr:13:7 src/context.cr 1 possible context found | Expr | Type | ---------------------------------------------------------------- | self | Context::MyClass | | @iv1 | String | | @iv2 | String | | @iv3 | Array(String) | | lv1 | Int32 | | lv2 | Float64 | | lv3 | Array(Int32) | | lv4 | Array(Array(Int32) | Array(String) | Float64 | Int32) |
ローカル変数に加え、インスタンス変数もしっかりとスコープ内に存在します。
$ crystal tool context
、ぜひ使ってみてください。