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
シンプルで非常に使いやすいので、これからもお世話になりたいと思います。
どんどん使っていきます。