builderscon tokyo 2018に参加してきました
概要
ブログを書くまでが以下略 のため、ブログ書きます。
はじめに(スタッフの方々)
準備/当日運営含めて、大変ありがとうございました + お疲れ様でした。はじめての参加でしたが、大変楽しかったです。
テーマになっていた「知らなかったを聞く」に満たされた、2日間でした。
普段、ごった煮のイベントはあまり行かないので、他の分野についての知見が広まりました。
来年も是非参加させていただきたいです。
良かった点/気になった点だけ記載しておきます。(Feedbackの意味も込めて)
良かった点
- 運営が基本的にとてもスムーズ
- 変な引っかかり等なく、トークを聞くことに集中できました
- 翻訳の用意がありがたかった
- (注意説明が、ムービーになっており面白かった)
気になった点
- 会場のキャパ問題
- 今回は? 人が多かったからなのか満席/立ち見が多かった気がします
- また、ランチセッションも早く並べた人限定という部分が少し気になりました。(ちなみに2日ともいただきました。)
- Webページのタイムテーブルで会場名がヘッダー固定ではなかった点
- 場所が何度かわからなくなりました..
- スライドが見づらいことが多かった
- 光の問題やスライド自体の問題?等で、文字が見えないことが何度かありました..
- ただ、事前に共有いただけていたので手元で見ながら聞けました
トーク一覧
下記のGistに各トークのメモ書きを記載しております。
(諸事情により、しっかりメモを取っています。)
https://gist.github.com/midorigreen/7409399469c39eeb0f96214d33b76eae
TimeTable
1日目
Envoy internals deep dive
Matt Klein@mattklein123 さんが直々に、Envoyの設計についてお話されていました。 所々、わからなくなっていきましたが、「観測可能性」と「ロックを起こさない設計」の2点について印象に残っています。 プログラムの設計をする際に見返したいスライドだと思いました。
ランチセッション (サイボウズ株式会社): Kubernetes で実現するインフラ自動構築パイプライン
日毎に、VPCから作り直している話は、以前一度聞いたことがありましたが、驚きです。
Algorithms in React
Reactほとんど書いたことないのですが、内部実装が気になったので聞きました。 LinkedList + byteをうまく利用して、高速化を図っている部分が印象的です。
事前知識なしで理解する、静的検査のいろは
早足で進むのがもったいないくらい、まとまってて勉強になる内容でした。あと、スライドが好みで真似したくなりました。
静的検査の教科書的な網羅性で、やりたくなったら読み返すと思います。
機械学習を用いず数学でゲーム内の需要予測をする
数学ががっつり?というほどではないですが、出てきて講義感があって面白かったです。 分析に携わる仕事をしていることもあり、分析の原則について知れてよかったです。(知らなかったのがまずそうです..)
JavaCardの世界
2日間の中での個人的ベストトークでした。(※ 実際のベストトークもこちらでした!!)
Java Cardという全く知らない世界の、めったに外に出てこない知見が山盛りでした。
また、発表されていた方のプレゼンスキルが高く感じました。
特に、このあたりが気になりました。
- 各仕様を正確に理解した上での、網羅的な説明
- 質問への正確の返答のための聞き返し
- (随所で笑いを生み出す力..)
あそこまで、ある技術に対して細かい点まで抑えられている事自体がすごいと感じましたし、詳しい分野を作りたいなと思いました。
(ここまでニッチではなくても良いですが...)
lld − 開発ツールの主要コンポーネントの1つをスクラッチから作成した話
tcfmの @rui314 さんの lld に関する発表でした。 実際に作られたlldに関しても面白い話でしたが、「勇気を持って自分が正しいと思う設計を突き通す」というお話がとても印象的です。 あと、速度を上げたければ データ構造 をうまく設計する必要があるとおっしゃっていた点も勉強になりました。
Conference Dinner
何人かの方々とお話できました!! (珍しい)
2日目
全てのエンジニアに知ってもらいたいOSの中身について
OSの中身? ≒ CPUのお話でした。CPUの歴史的背景がゴロゴロ出てきて、面白かったです。
高集積コンテナホスティングにおけるボトルネックとその解法
Linuxのボトルネックをガツガツ潰していくお話でした。手になじませるツールをいくつか持っておくという部分が印象的です。 Linux系 + Go系でツールをゴリゴリ使えるようになりたいです。
ランチセッション (株式会社VOYAGE GROUP)
AjitoFmの公録が聴けて、純粋に楽しかったです。普段Podcastで聞いている声が目の前から聞こえてくる、不思議な感覚でした。
ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ
聞いてきた中で、最も仕事感のある内容で、ちょっと胃が痛くなりそうでした。高要求に対して、AWSのツールを活用して、 要件を満たしていました。その結果、ユーザに対して素晴らしい機能を提供できており、こういったことができる職業エンジニアになりたいと思いました。
業務時間で書いたパッチは誰のもの? OSS 活動にまつわる罠
とても珍しい、会社のOSS Policyに対するお話でした。基本的には、各社員が自由にやれるとい方向に倒れており、すごいなと思いました。
Building Self-Hosted Kubernetes
k8sをself hostするお話です。self host自体がよくわかっていなかったので、そこの知識を埋められてよかったです。 実際に、self hostを動かしてみてどうだったかとのお話がまた聞きたいです。
Extending Kubernetes with Custom Resources and Operator Frameworks
全セッションの中で最も難しかったです。(途中からさっぱりわからなくなっていきました..)
k8s周りについての理解が浅かった部分が大きかったです。ただ、k8sの設計思想(あのロゴの意味)等が知れました。
Lightning Talks
なんでもありのトークで、LTっぽくて楽しかったです。 下記が印象に残っています。
- Macがいやだからブラウザで動くエディタを作成(https://nedi.app/)
- めちゃめちゃ速くてびっくりしました
- 画像加工 (kaoriyaさん)
- 衝撃でした
- カオスエンジニアリングの文脈でネットワークの検証
- ファミコンエミュレータでBest Practiceを目指す
- 登壇するための背中を押せていただける話
感想
とにかく、面白いイベントでした。もともと、他の分野の話を聞いて知見を広めたいとの目的で参加したので、完全に達成された気でいます。 あとは、聞くだけではなくて手を動かしていくことが大切だと思うので、ゴリゴリコード書いていきます。 (発表もできたらいいなぁともちょっと思っています。)
Go-Cloudで利用されているDIツールWireについて
概要
Go-Cloud Projectで利用されている、 Wire
と呼ばれる
Dependency Injection Tool について触ってみました。
(README.md
を試した形です)
Install
wire
は go get でインストールします。
go get github.com/google/go-cloud/wire/cmd/wire
実装
基本的な使い方
ProviderとInjecterという2つの概念を持ちます
Provider
Providerは、依存させたいstructの実体を返却します。
例)
依存させたいstructの実態を定義します。
// foo.go type Foo struct{ Name string }
Provider関数を定義します。
func ProviderFoo(name string) Foo { return Foo{ Name: name, } }
Providerの利用元も実装します。
(今回は1つですが) ProviderSetを定義することで、複数のProviderをまとめて処理します。
main.go
// ProviderSet var SuperSet = wire.NewSet(ProviderFoo) func main() { // flagで名前を切り替えられるようにしてみます n := flag.String("n", "foo", "foo name") flag.Parse() foo, err := setUp(context.Background(), *n) if err != nil { log.Fatalln(err) } // fooの名前を出力 fmt.Println(foo.Name) }
Injector
Injectorは、Provider関数を利用して実体を実装へinjectします。
injectorのコードは仮実装を元に、wire
が生成してくれます。
例)
Injectorの仮実装を定義します。
コード生成の元コードのため、buildタグを付与して
build時に利用されないようにします。
injector.go
// buildタグを付与 //+build wireinject // 実装 func setUp(ctx context.Context, name string) (Foo, error) { // ProviderをBuildする wire.Build(SuperSet) // 特に意味はない return Foo{}, nil }
ここで、injectorの実装を生成していきます。
下記コマンドを実行します。
(go getで入れているので、バイナリが$GOPATH/bin配下に配置されてます。)
% wire
wire
コマンドを実行すると、下記のような wire_gen.go
が生成されます。
参考) wire_gen.go
// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main import ( context "context" ) // Injectors from inject.go: func setUp(ctx context.Context, n string) (Foo, error) { foo := ProviderFoo(n) return foo, nil }
実行
wire_gen.go
が生成された段階で、buildして実行してみます。
% go build -o wire-sample
(補足)
buildタグで、!wireinject
となっているため go build
時は、
injector.go
の代わりにwire_gen.go
が利用されます。
実行
% ./wire-sample foo # ちゃんとフラグで渡した値が利用されている % ./wire-sample -n bar bar
ちなみに、一度 wire_gen.go
を生成したあとで、修正したい場合は、 go generate
を利用します。
# 再ビルド % go generate && go build -o wire-sample
Tips
① 独自型を定義してProviderへ渡す
Providerに、一般的な型(string, int, etc..)を利用すると、コードを生成する際に一意に定まらず、期待しない動作になる可能性があります。
そのため、独自型で定義してsetUpの引数に渡してあげることで、確実に狙ったProviderの引数に渡すことができます。
例)
injectしたいstruct
type Foo struct { Name: string } type Hoge struct { Hoge: string } type FooHoge struct { Foo Foo Hoge Hoge }
providerの実装
// 型定義 type fooName string func ProviderFoo(name fooName) Foo { return Foo{ Name: string(name), } } func ProviderHoge(name string) Hoge { return Hoge{ Name: name, } } func ProviderFooHoge(foo Foo, hoge Hoge) FooHoge { return FooHoge{ Foo: foo, Hoge: hoge, } } var SuperSet = wire.NewSet(ProviderFoo, ProviderHoge, ProviderFooHoge) func main() { fh, _ := setUp(ctx, "foo", "hoge") fmt.Println(fh.Foo.Name) fmt.Println(fh.Hoge.Name) }
injector.go
func setUp(ctx context.Context, fn fooName , n string) (FooHoge, error) { wire.Build(SuperSet) return Foo{}, nil }
↓ go generate
// generateした際に、stringのままだとFoo/Hogeの // どちらの名前かわからなくなってしまう func setUp(ctx context.Context, fn fooName , n string) (FooHoge, error) { foo := ProviderFoo(fn) hoge := ProviderHoge(fn) fooHoge := ProviderFooHoge(foo, hoge) reutnr fooHoge, nil }
所感
GoでDIする際に、あまりツールを利用できていなかったので、 利用が増えてくれば、実コードに入れるのもありかと思いました。 DIに関しては、 Guice を一度触れていたので、比較的すんなり入ってきました。 テスタビリティがきちんとあがっているかは、テスト書いてみて確認したいです。
参考
実践 Python データサイエンス受講 (No.1)
概要
【世界で5万人が受講】実践 Python データサイエンス | Udemy
をぼちぼち受講していっています。
序盤のあたりまで、受講したので内容についてまとめておきます。
データサイエンス周りの基礎知識をつけることがゴールかなと思っています。
内容
はじめに
基本的にはJupyter Notebook上にサンプルコードを書いて実装しています。
data-kaggle/learn at master · midorigreen/data-kaggle
Jupyter Notebook
(記載するまでもないですが)
- ブラウザ上で、プログラムを実行できるツール
- プログラムだけでなく、グラフの可視化やMarkdownの記載等を利用して、実行した処理を記録
- Machine Learningにてデファクトで利用されているツール
- IPython(Pythonのinteractive shell)をベースに、様々な言語(40程度)に対応
- ipynb拡張子で保存され、GitHub上で見ることも可能
numpy
Pythonの行列計算用のライブラリで、作成・計算をはじめ様々な機能を持っています。
import
import numpy as np
行列の作成
# array([0, 1, 2, 3, 4]) arr = np.array([0, 1, 2, 3, 4]) arr = np.arange(5) # ランダム arr = np.randam.randn(5) # array([[0, 1, 2, 3, 4]) # [0, 1, 2, 3, 4]]) arr2 = np.array([0, 1, 2, 3, 4],[0, 1, 2, 3, 4]) # array([[0, 1, 2], # [3, 4, 5], # [6, 7, 8]]) arr3 = np.arange(9).reshape((3, 3))
行列の操作
# (行, 列) arr.shape # コピー arr_copy = arr.copy() # 転置 arr3.T # 行列入れ替え arr3.swapaxes((0, 1)) # 条件式 (条件, trueのとき, falseのとき) np.where(a > 0, 0, arr)
行列の計算
# 平方根 np.sqrt(arr3) # 掛け算 arr1 * arr2 # 内積 np.dot(arr1, arr2) # 平均 arr.mean() # 標準偏差 arr.std() # 分散 arr.var() # ソート arr.sort() # 逆順 arr[::-1] # 重複 np.unique(arr) # contains np.in1d([0, 10, 20], arr)
行列の外部処理
# 保存 np.save('my_arr', arr) # 読み込み np.load('my_arr.npy') # zip保存 np.savez('my_arr2', x=arr, y=arr2) zarr = np.load('my_arr2') # 添字アクセス zarr['x'] zarr['y']
matplotlib
- Pythonの2Dのプロットライブラリ
- グラフを描画することができる
Import
import matplotlib.pyplot as plt
pandas
- データ構造と演算を提供するPythonのライブラリ
import
import pandas as pd
Series
ラベル付きの配列(1次元)
# 生成 se = Series([0, 1, 2, 3]) # ラベル付き se1 = Series([0, 1, 2, 3], index=['A', 'B', 'C', 'D']) se1['A'] # 辞書型変換 se1.to_dict()
DataFrame
ラベル付きの行列(2次元)
# 生成 # Clipboardから(Wikipedia等より表形式をコピー) df = pd.read_clipboard() df2 = {'City': ['LA', 'SF', 'NYC'], 'Population':[30000, 20000, 8000]}
環境
# Anaconda利用 % python -V Python 3.5.2 :: Anaconda 4.1.1 (x86_64)
所感
まずは序盤として、Jupyterの利用方法から、numpyの基本までを記載しました。感想としては、行列の扱いが簡単にできて、Pythonが利用される理由の一端に触れた気がしました。pandasについては、もう少しあるので編集する形にしようかと思います。
参考
Go実装の最適化ゲームをしてみた
概要
同僚が「このコード書ける Java
のライブラリない?」 と言ってきたので、
Go
で実装し返しました。(遊び)
書いたコードがひどそうだったので、最適化をするゲームをしてみました。
結論、あまりいい感じではないですね。
お題
配列が与えられた際に、 指定した最小/最大サイズの文字列を前から順に結合して取得したい とのことでした。(何言ってるかわからない)
例
例を挙げるとわかりやすいかと思います。
input: [a, b, c, d, e] => output: [ab, abc, abcd, abcde, bc, bcd, bcde, cd, cde, de]
実装
パート1
まず、最初に思いついて書いたコードが下記になります。
なんかこう色々まずそうです。
Go Playground
func initialShingle(min, max int, arr []string) []string { res := []string{} if min > max { return res } for i := 0; i < len(arr); i++ { cmin := min for j := i; j+cmin < len(arr)+1; j++ { if len(arr[i:j+cmin]) > max { break } var s string for _, v := range arr[i : j+cmin] { s += v } res = append(res, s) } } return res }
閑話休題
とりあえず、動作確認のためテストコードを書きます。
min/maxの値の境界値等を Table Drive Test
で記載しました。
https://github.com/midorigreen/shingle/blob/master/main_test.go#L35
var cases = []struct { in in out []string }{ { in: in{min: 2, max: 1, arr: []string{"a", "b", "c", "d", "e"}}, out: []string{}, }, { in: in{min: 2, max: 2, arr: []string{"a", "b", "c", "d", "e"}}, out: []string{"ab", "bc", "cd", "de"}, }, { in: in{min: 2, max: 3, arr: []string{"a", "b", "c", "d", "e"}}, out: []string{"ab", "abc", "bc", "bcd", "cd", "cde", "de"}, }, { in: in{min: 2, max: 5, arr: []string{"a", "b", "c", "d", "e"}}, out: []string{"ab", "abc", "abcd", "abcde", "bc", "bcd", "bcde", "cd", "cde", "de"}, }, { in: in{min: 2, max: 100, arr: []string{"a", "b", "c", "d", "e"}}, out: []string{"ab", "abc", "abcd", "abcde", "bc", "bcd", "bcde", "cd", "cde", "de"}, }, } func TestInitialShingle(t *testing.T) { for _, c := range cases { res := initialShingle(c.in.min, c.in.max, c.in.arr) equal(t, res, c.out) } }
ベンチマークも書いたので、この結果が元になります。
% go test -benchmem -run=^$ github.com/midorigreen/shingle -bench ^BenchmarkInitialShingle$ goos: darwin goarch: amd64 pkg: github.com/midorigreen/shingle BenchmarkInitialShingle-4 3 388369200 ns/op 354791952 B/op 4621681 allocs/op PASS ok github.com/midorigreen/shingle 1.513s
パート2
alloc回数を減らすために、返却値の初期化を1回にします。
Go Playground
func shingle2(min, max int, arr []string) []string { // 省略 // for alloc array maxLen := len(arr) resLen := 0 for maxLen > 0 { resLen += maxLen maxLen-- } res := make([]string, resLen) // 省略 }
ベンチマーク結果
% go test -bench . -benchmem goos: darwin goarch: amd64 pkg: github.com/midorigreen/shingle BenchmarkInitialShingle-4 3 364788315 ns/op 354790757 B/op 4621679 allocs/op BenchmarkShingle2-4 3 484458838 ns/op 355455082 B/op 4621651 allocs/op PASS ok github.com/midorigreen/shingle 4.093s
悪くなってますね..
パート3
slice->stringの処理で文字列結合をしている部分を修正しました。
strings.Join([]string, string)
を使ってます。
Go Playground
func shingle3(min, max int, arr []string) []string { // 省略 res = append(res, strings.Join(arr[i:j+cmin], "")) // 省略 }
% go test -bench . -benchmem goos: darwin goarch: amd64 pkg: github.com/midorigreen/shingle BenchmarkInitialShingle-4 5 330830989 ns/op 354791379 B/op 4621680 allocs/op BenchmarkShingle2-4 5 332415947 ns/op 355455014 B/op 4621651 allocs/op BenchmarkShingle3-4 20 59744819 ns/op 27479328 B/op 186132 allocs/op PASS ok github.com/midorigreen/shingle 7.958s
速度もalloc回数も改善されました。
(補足) strings.Join()関数
実際の実装を見ると、以下の形になってます。
len(array)<=3
までは+で結合している- それ以降は、まずスライス長を確保している
- 結合するのではなくstringをbyte配列にcopyしている
- copyはstring->[]byteへコピーできる模様 doc
(As a special case, it also will copy bytes from a string to a slice of bytes.)
// Join concatenates the elements of a to create a single string. The separator string // sep is placed between elements in the resulting string. func Join(a []string, sep string) string { switch len(a) { case 0: return "" case 1: return a[0] case 2: // Special case for common small values. // Remove if golang.org/issue/6714 is fixed return a[0] + sep + a[1] case 3: // Special case for common small values. // Remove if golang.org/issue/6714 is fixed return a[0] + sep + a[1] + sep + a[2] } n := len(sep) * (len(a) - 1) for i := 0; i < len(a); i++ { n += len(a[i]) } b := make([]byte, n) bp := copy(b, a[0]) for _, s := range a[1:] { bp += copy(b[bp:], sep) bp += copy(b[bp:], s) } return string(b) }
感想
あまりいい感じの改善にはならなかったですね。
結局、string結合がボトルネックになっていたのでそこを改善すれば、
速度的にはマシになりました。
strings.Join()の挙動とcopyの挙動を知れたのが収穫です。
(よく考えると、どこがネックになっているかの計測を第一にしないといけなかったですね)
書いたコード
Write Code Every Day (1年目)
概要
Write Code Every Dayを1年間達成しましたので、感想云々を記載します。
一応、日付ずらし等はやらずにいけました。
(ユーザーミスが1日だけあったくらいですかね..)
Write Code Every Dayとは?
毎日コード書いて commit
して、GitHubに芝を生やすことです。
昨年のこの時期に、 @t_wada
さんのスライドを見てはじめてみました。
(元ネタはこれかな) John Resig - Write Code Every Day
@t_wada
さんのスライド
Write Code Every Day // Speaker Deck
結果
(色薄..)
作ったもの
主にGolangの勉強系で作ったものが多いです。 (90%くらい..)
gosns
- Messaging Sever です
- Amazon SNSを初めて触れて、書いてみたかったのでGoで書いてみました
- Pub/Sub Modelをイメージして作成してます
mercari/go-httpdoc
を使ってテストコードから、API Docを生成したことをよく覚えてます
gtrello
- 日報作成ツールです
- 毎日簡単に書きたくて作りました (まだ使ってます)
- Trelloの情報をSlackへ送信する流れです
$ gtrello
→ editor open(所感記入) →#times_midori
へ配信
- Trello用のClient (
BurntSushi/toml
) をガッツリ使ってます- こういうClient利用をきれいにテスト書かねばというのが課題です
- Go標準のtemplateを利用して、Markdown生成とかしてました
- (Slack投稿にしたので、最終的にはあんまり残ってないです..)
gmd
- コマンド保存ツールです
- 同じコマンド打つの辛いなぁと思って作りました
- 現在はhistoryに置き換わって使ってないですね…
- history + peco (参考: pecoる - Qiita)
- コマンド自体をまるっと保存します
- できること
- 保存
- 実行
- 一覧
gchat
- チャットサーバーです
websocket
ってどんな感じなんだろうと思って作りました- (まだよくわかってないですね..)
gorilla/websocket
をwrapしているだけって感じでサクッと作れました
その他
- 作りかけ放置多数
原則の達成度
- 毎日コード書くこと
- 達成度 70%
- NG Point
README.md
更新- メモ等のcommit
- NG Point
- 達成度 70%
- 意味のあるコードを書くこと
- 達成度 70%
- NG Point
- 上記と同様
- NG Point
- 達成度 70%
- 深夜24時前に終わらせること
- 達成度 80%
- NG Point
- 24時超えのcommitは少しはあった
- NG Point
- 達成度 80%
- 書いたコードをGitHubのOSS化すること
- 達成度 100%
やってみての感想
メリット
- 毎日コード書く(commitする) 習慣 は完全に身についた
- ほぼストレスなくできるようになった
- 頭の片隅にいつも、今日のcommitはちらつく
- (勉強する習慣を社会人1年目から作れたのは良かった)
- Goがとても好きにになった
- 新しいものに触れるととりあえず手を動かすようになった
- 芝生えるしちょうどいいと思って、コード書いてみる
- gRpc
- GraphQL
- Eclipse Collection
- ML
- etc..
- 芝生えるしちょうどいいと思って、コード書いてみる
デメリット
- インプットが少なくなりがち
- 本読んだり等が二の次になってしまう
- つなげるための苦肉の策
REAMD.md
更新- (正直結構やりましたね、
README.md
だけの更新..)
- (正直結構やりましたね、
- 家に帰るのが間に合わずスマホからcommit
- 飲み会で遅くなり、commit → pushできるツールを探しました..
- source (https://source.ianmcdowell.net/)
- これでできましたが、pushするためには課金(500円?)が必要で..
- 泣く泣く課金しました…
- (後日、一緒に飲み会に行っていた同期が謎に500円くれました)
- 24時超えcommit
- 次の日できなさそうな時、やってました
今後
習慣化しているので、続けていこうかと思います。
エンジニアである以上、日々手を動かしていけるようにしていきたいです。
2年目
README.md
更新頻度の削減- ちゃんとコード書く
- コード書くための時間づくりも大事にする
- インプット → アウトプットの習慣化
- 本をもっと読みたい
- 基礎知識が低すぎる課題
- 本を読んだことを活かしてコードを書く
- 本をもっと読みたい
- 続けること
- 2年目もがむしゃらにとにかく続ける
- OSSへcommitする
- Libraryもしくは有用なツールを公開する
- ちゃんと使えるものを作りたい
- 設計からしっかり実施したもの
- テストコードを書く
まとめ
1年続けてみて、個人的には良い習慣かなと思いました。
基本サボり症である程度の強制力があるものがないと続かない人には、
向いているかと思います。(自分はこれです)
作ったもの等は、稚拙なものが多いですがこれも実力の内なので、
2年目はまた違った結果がみせれると良いかなと思います。
ijaas導入時に詰まった点
概要
ijaasを導入に当たって、変なところで詰まったので残しておきます。
ijaasとは
Make IntelliJ as a Java server that does autocompletion for Vim.
IntelliJをサーバーとして立てて、Vim
からAPI経由で各種機能を
利用できるようにしている模様です。
導入の基本は、 README.md
に記載の通りの手順で問題ないはずです。
詰まった点
1. PluginがInstallできない
Setting > Plugins > install plugin from disk
実行時に、下記エラーが発生
解消
IntelliJのバージョンが合ってなかったため、発生していた模様です。
build.gradle
def intellijVersion = 'IC-2017.1.5' if (project.hasProperty('intellij.version')) { intellijVersion = getProperty('intellij.version') }
intellij.version
で切り替えができる模様のため、
build.properties
を追加して上げれば良いです。
intellij.version=IC-2017.2.6
2. IntelliJ上からbuildPluginするとIdea取得で失敗
S3より、Ideaを取得する部分で失敗していました。
解消
コンソールより実行で解消できました。
% gradle buildPlugin
3. NeoVimから実行できない
ch_open
がNeoVimに実装されていない(?) 関係上、利用できませんでした。
(IntelliJへの接続に利用しているため、全般の機能が利用不可かと..)
if exists("$IJAAS_PORT") let s:ch = ch_open('localhost:' . $IJAAS_PORT) else let s:ch = ch_open('localhost:5800') endif
解消
Vim
を使う。
4. 保存時の ijaas#buf_write_post()
でTimeout
一旦コメントアウトしております。
( complete()
や organize_import()
は利用できました。)
5. IntelliJで該当Projectを起動していないと動作しない
該当ProjectをIntelliJで開いた状態で、利用する必要があるみたいです。
所感
まだ、実用的なコードで試せてないですが、
オートコンプリートはきれいに動作してました。
その他の機能に関しては、上手く動かせない部分もありました。
(機能を理解できていないからかと..)
あと、 メソッドジャンプ機能 が欲しいです。
vim-goの便利コマンド一覧
概要
Goを開発している際に、vim-goを利用しています。
最低限のコマンドしか利用できていなかったため、
便利なコマンドを再洗い出ししてみます。
(個人的なまとめの意味合いが強いです。)
Commands
下記を参照しております。
vim-go/vim-go.txt at master · fatih/vim-go · GitHub
:GoRun
go run
コマンドに相当します。
vim上から実行できるところが便利です。
:GoBuild
go build
コマンドに相当します。build後のバイナリは排出しないです。
buildが成功するかどうかを確認する際に利用すると便利です。
成功すると、下記のように出力されます。
vim-go: SUCCESS
失敗すると、quickfix windowに一覧が出力されます。
1 main.go|16| syntax error: unexpected semicolon or newline, expecting comma or } Quickfix go build -i . errors vim-go: FAILED
:GoDef
カーソル以下の、宣言元にjumpできます。
実際の実装がどうなっているか確認したりする際に利用します。
gd
で同等の動作をします。
(基本的には、 gd
で移動することが多い印象です。)
:GoCallers
カーソル以下のfuncの、呼び出し元を一括検索できます。
(ファイル全検索していたのが、馬鹿らしく思えます..)
注意点 として、複数packageで検索したい場合は、 :GoGuruScope
でスコープを設定します。
(どのディレクトリ以下で検索をかけたいかを設定するイメージです。)
:GoGuruScope github.com/midorigreen/gprof
selectPeco()のカーソル上で
:GoCallers
quickfix window
1 main.go|93 col 6| github.com/midorigreen/gmd.selectPeco is called from these 3 sites: 2 /Users/midori/src/golang/src/github.com/midorigreen/gmd/exec.go|28 col 28| static function call from github.com/midorigreen/gmd.cmdExec 3 /Users/midori/src/golang/src/github.com/midorigreen/gmd/hist.go|38 col 28| static function call from github.com/midorigreen/gmd.cmdHist 4 /Users/midori/src/golang/src/github.com/midorigreen/gmd/del.go|29 col 25| static function call from github.com/midorigreen/gmd.cmdDel
:GoCallstack
カーソル以下のfuncのcallstackがquickfix windowで見れます。
(こちらも :GoGuruScope
の指定が必要です。)
1 main.go|120 col 7| Found a call path from root to github.com/midorigreen/gmd.run 2 main.go|120 col 6| github.com/midorigreen/gmd.run 3 main.go|138 col 13| static function call from github.com/midorigreen/gmd.main
:GoTest
テストを実行します。
:GoTestFunc
カーソル以下のtest funcのみテストを実行します。
:GoDoc
カーソル以下のGoDocを別windowで参照することができます。 (Shift+k と同等の認識です。)
:GoDocBrowser
カーソル以下のGoDocをブラウザ上で参照することができます。
わざわざGoDocを検索する手間が省けます。
[range]:GoAddTags
range指定した、structにタグを自動で追加してくれます。
Before
type Prof struct { Cores []Core Model string ModelName string CacheSize int32 }
After
(defaultはjsonタグ)
type Prof struct { Cores []Core `json:"cores"` Model string `json:"model"` ModelName string `json:"model_name"` CacheSize int32 `json:"cache_size"` }
- dbタグ =
[range]:GoAddTags db
- omitempty =
[range]:GoAddTags json,omitempty
:GoFillStruct
structの宣言時に、literalをdefault値で埋めてくれます。
初期化時に、各literalを打たなくて良いのが楽です。
Before
prof := Prof{}
After
prof := Prof{ Cores: nil, Model: "", ModelName: "", CacheSize: 0, }
:GoRename [to]
カーソル以下の文字を、一括でrenameしてくれます。
呼び出し元も、合わせて修正してくれろところが便利です。
func
, struct
, 変数名
のそれぞれ動作可能です。
:GoPlay
開いているファイルをGo Playgroundで見ることができます。
サンプルコード書いて、展開する場合とかに便利そうです。
所感
他にもまだまだ眠ってそうですが、追加され次第、追記していく形を取ろうかと思います。
ここまで揃っていると、vimで十分な効率で開発できそうです。