私が歌川です

@utgwkk が書いている

Go Conference 2024 登壇した #gocon

Go Conference 2024に参加し、登壇してきました。

登壇しました

Dive into gomockというタイトルで発表しました。2トラックのどちらかで40分トークかな? と思っていたら2部屋ぶち抜きでトークだったのでビビっていました。

発表資料はこちらです。

speakerdeck.com

gomockの内部実装を見て、なぜライブラリの内部実装を見るのがよいことなのか、という話をしました。reflectパッケージが好きなので合間にreflectパッケージの話もしています。つまり主題が3つあるわけですね。

  • gomockの内部実装を見よう
  • リフレクションを知ろう
  • なぜライブラリの内部実装を見るのか知ろう

今回はgomockの実装を掘り下げることで、魔法のように見えるイディオムの裏にある処理を知ろう、という方向性でやりました。今回の発表でgomockの内部実装を全員が完全理解できたかは分かりませんが (理解できていたらすごいと思います)、これをきっかけにライブラリの実装を読むことの楽しさや効能について多くの人に知ってもらえたら幸いです。

ポスト見ました

自分の想像よりもXのポスト (旧Twitterのツイート) が盛り上がっていそうでしたね。いくつかお返事を書いてみています。

m.EXPECT().MethodName(arg1, arg2).Return(ret1, ret2) のうち .MethodName(arg1, arg2) の部分は、任意の値もしくはMatcherを受け付けられる必要があるので、パッと実現できるかは分からないですね。

.Return(ret1, ret2) の部分については、mockgenに -typed というオプションを渡すことで、メソッドの返り値をany型じゃなくて本来の型にすることができます。具体的には Do DoAndReturn Return メソッドに型がつくようになります。

モックするメソッドごとに *gomock.Call をラップした型をコード生成する、という仕組みで動いているため、代わりに生成されるコードの量は増えることになりますね。

github.com

Cond Matcherの String メソッドが返す値は adheres to a custom condition という文字列です。つまりカスタム条件であることしか分からない!! こういう場合はWantFormatterを通すほうがテスト失敗時のログが分かりやすくなりそうですね。

https://github.com/uber-go/mock/blob/893ee9cb6b098575f0bad39eaf4d02eeec917633/gomock/matchers.go#L109-L111

わかる〜うまくシグネチャを設計していくとジェネリックな感じにできるのかも。もしくはそういうライブラリがある?? 誰か知ってたら教えてください。

推測ですが、struct定義を関数内に閉じ込めることで名前を消費しないようにしているんですかねえ。これぐらいで済むなら自分でもこういう感じで書いて済ませるかも。

発表資料を作っているときはこの観点は抜けていたのですが、確かに!! 難しいことをやるからには相応の解説をコード中にコメントとして残して、なんとかメンテナンス可能にしていこう、という気概を感じますね。

Do メソッドが返り値を使わないのは過去の経緯があるようですね。godocにも「下位互換性のために返り値を無視している」ということが書いてあるので、基本的に DoAndReturn メソッドを使うほうがよさそうです。

おそらく昔は Do メソッドと Return メソッドを組み合わせる、という使い方しかできなかったのかも。DoAndReturn メソッドが追加されたときの様子を見るにそんな感じなのかな?

github.com

github.com

発表見ました

tenntennさんのイテレータの話は、Goの最新の言語機能を速習できるという感じでした。ジェネリクスを活用してよくあるスライス操作を簡潔に書くためのライブラリは既にありますが、どうしてもスライスを経由するので実行効率が気になるところでしたが、イテレータを組み合わせることで効率と書きやすさ・表現力を両立できることに期待したいですね。これは自分でもイテレータを駆使してなにかを作ってみることで知識が定着するのでしょう。

Iwaminさんのフィーチャーフラグを自動計装する話は、なかなか興味深い切り口でおもしろかったです。フィーチャーフラグとその運用には昔から今まで悩まされていたところなので、簡単に入れて外せるようになると夢っぽい。if文を起点とするほかにbuild tagsでファイルごと差し替える、みたいなアプローチもあるのかな?

karamaruさんの "Fixing For Loops in Go 1.22" を深く掘り下げた話は、よくあるイディオムとその修正というだけにとどまらず本当に深く掘り下げられていておもしろかったです。発表資料を拝見した感じだと、他にもいろいろなトピックや取り組みの話題がありそうで、枠が20分しかないのがもったいないぐらいでした。fmt.Println 関数で変数をエスケープさせられる例がよかったです。

ありがとうございました

参加者のみなさま、運営のみなさま、現地でお話ししたみなさま、ありがとうございました。40分トークで2部屋ぶち抜き、ライブラリの実装を読んでいく、というトークを聞いてもらうという感じで緊張感がありましたが、おもしろかったと言っていただけたのでよかったです。

次回のGo Conferenceでも何か発表したいですね。自分で作ったものの話とか、もうちょっと別のテーマで話せるといいかも。あるいは会社の人に登壇してもらうとか……。