https://github.com/motemen/gore
GoでREPLといえばgoreとのことなので、早速使ってみる。
インストールする
まずはgo getでインストール
GO111MODULE=off go get -u github.com/motemen/gore/cmd/gore
READMEのInstallation[https://github.com/motemen/gore#installation]
を見ると以下もインストールすることが推奨されているので、
こちらもgo getしておく。
# 入力補完
GO111MODULE=off go get -u github.com/mdempsky/gocode
# 出力ハイライト
GO111MODULE=off go get -u github.com/k0kubun/pp # or github.com/davecgh/go-spew/spew
【2019/12 追記】
APIドキュメントの参照のために以前はgodocが必要だった。
現在は不要(go docコマンドを使用)なので削除。
Fix :doc command in Go 1.12 by rzyns · Pull Request #117 · motemen/gore
drop godoc requirements from README.md by Songmu · Pull Request #142 · motemen/gore
使ってみる
以下で実際に使ってみる。
ターミナル上でとりあえずgoreと打ってみると、以下のような出力となる。
$ gore
gore version 0.4.1 :help for help
gore>
早速REPLが起動しているよう。
まずは促されるがままに:helpと打つ。
gore> :help
:import <package> import a package
:type <expr> print the type of expression
:print print current source
:write [<file>] write out current source
:clear clear the codes
:doc <expr or pkg> show documentation
:help show this help
:quit quit the session
利用できるコマンドの一覧が出力されたので、ひとつずつ試していこうと思う。
:importを使ってみる
gore> :import encoding/json
gore> b, err := json.Marshal(nil)
[]uint8{
0x6e, 0x75, 0x6c, 0x6c,
}
nil
:importコマンドは説明の通り、goreのセッション内で使用するパッケージの
インポートを行う。
上の例では事前にimportすることでencoding/jsonパッケージを使用できるようにしている。
事前にimportしない場合は以下のような出力になる。
gore> b, err := json.Marshal(nil)
# command-line-arguments
/tmp/991290791/gore_session.go:10:25: undefined: json
error: exit status 2
exit status 2
:typeコマンド 【2019/12 追記】
Implement type command by itchyny · Pull Request #127 · motemen/gore
上記PRで実装された。引数に変数などを渡すと、その変数の型を返してくれる。
gore> b, err := json.Marshal(nil)
[]uint8{
0x6e, 0x75, 0x6c, 0x6c,
}
nil
gore> :type b
[]byte
gore> :type err
error
:docコマンドを使う
次に:docコマンドを使うと、godocのドキュメントがひける。
REPL上での出力は以下のような感じ。
gore> :doc json.Marshal
package json // import "encoding/json"
func Marshal(v interface{}) ([]byte, error)
Marshal returns the JSON encoding of v.
...
パッケージ内の関数は.繋ぎで入力してもうまくいくよう。
また、変数のメソッドなども、変数のまま入力すればうまくいく。
とても便利。
これも事前にimportしておく必要がある。
importしてなかった場合は以下の出力となる。
gore> :doc json.Marshal
error: doc: cannot determine the document location
:printコマンド、:writeコマンド、:clearコマンド
試しに打ってみると、以下のような出力となる。
gore> :print
package main
import (
"github.com/k0kubun/pp"
"encoding/json"
)
func __gore_p(xx ...interface{}) {
for _, x := range xx {
pp.Println(x)
}
}
func main() { b, err := json.Marshal(nil) }
これを:writeコマンドによってファイル保存できる。
gore> :write example.go
Source wrote to example.go
:clearコマンド 【2019/12 追記】
Implement clear command by itchyny · Pull Request #119 · motemen/gore
ここで追加された:clearコマンドを使う。
gore> :clear
gore> :print
package main
import "github.com/k0kubun/pp"
func __gore_p(xx ...interface{}) {
for _, x := range xx {
pp.Println(x)
}
}
func main() {}
セッション中に定義したものを初期化できるようになった。
(上記ではfunc main()内にに定義していたb, err := json.Marshal(nil)が消えて
初期化されたことが確認できる)
【2019/12 追記ここまで】
:quitコマンドでgoreセッションから抜け、
先ほど保存したファイルの中身を確認。
gore> :quit
$ cat example.go
package main
import (
"github.com/k0kubun/pp"
"encoding/json"
)
func __gore_p(xx ...interface{}) {
for _, x := range xx {
pp.Println(x)
}
}
func main() { b, err := json.Marshal(nil) }
:printコマンドで出力したものと同じ内容となっていることが確認できる。
以上、ここまでがgoreセッション内でのコマンドとなる。
これらを駆使して快適なREPLライフを目指す。
goreコマンド自体のオプション利用
まずは--helpを渡して実行してみる。
$ gore --help
Usage of gore:
-autoimport
formats and adjusts imports automatically
-context string
import packages, functions, variables and constants from external golang source files
-pkg string
specify a package where the session will be run inside
-autoimportオプション
:importコマンドを使う手間を省略できるというもの。
$ gore -autoimport
gore version 0.2.6 :help for help
gore> b, err := json.Marshal(nil)
[]uint8{
0x6e, 0x75, 0x6c, 0x6c,
}
nil
-contextオプション
指定されたgoのソースファイルで使われているパッケージ群を
まとめて事前にインポートできる。
先ほど:writeコマンドで作成したexample.goを例として使用する。
$ gore -context example.go
gore version 0.4.1 :help for help
added file example.go
gore> :print
package main
import (
"github.com/k0kubun/pp"
"encoding/json"
)
func __gore_p(xx ...interface{}) {
for _, x := range xx {
pp.Println(x)
}
}
func main() {}
example.goで使用していたencoding/jsonをデフォルトでインポートすることができた。
-pkgオプション
-contextオプションと同様に.goファイルからパッケージの事前インポートができる。
こちらはパッケージ名を指定する。
先ほどのexample.goを作業リポジトリを作って配置し以下のようにする。
(例: github.com/Ken2mer/example)
$ gore -pkg github.com/Ken2mer/example
そして:printコマンドを打つとさきほど-contextオプションの時と
同じく以下の出力結果となる。
gore> :print
package main
import (
"github.com/k0kubun/pp"
"encoding/json"
)
func __gore_p(xx ...interface{}) {
for _, x := range xx {
pp.Println(x)
}
}
func main() {}
こちらは複数ファイルを持つパッケージなどに対し一括でインポートできるので有用そう。
おわりに
以上で使い方が網羅できたかと思います。
簡単な動作確認のために、わざわざmain.goを作成してgo runと実行していたところが
コマンド一発で済ませられるようになった印象を受けました。
このツールの作者自身も
REPL といいつつ実は裏ではそれまでの入力を順番に実行するソースコードを生成して go run しているだけ
とおっしゃっています。
- 参考: gore作者ブログ記事
http://motemen.hatenablog.com/entry/2015/02/go-repl-gore
シンプルで非常に使いやすいので、これからもお世話になりたいと思います。
どんどん使っていきます。