SlideShare a Scribd company logo
1 of 50
Download to read offline
    による
Go
コードジェネレーション
kamakura.go #3 2018/1/20
株式会社 HDE 牧大輔 (@lestrrat)
Brute-force Code Generation In Go
筋 肉
• @lestrrat
• Perl/Go hacker, author, father
• Author of github.com/peco/peco
• Organizer for builderscon
agenda
1. go-slack
2. 私流コードジェネレーション
3. コードジェネレーションtips
4. 反省とまとめ
<宣伝>
http://blog.builderscon.io/entry/call-for-sponsors-2018
スポンサー募集中!!!
go-slack
クライアント
• APIが完全自動生成 (endpoints.jsonを編集)
• APIが完全にGoogle風味 (google.golang.org/api)
自動生成前提
→大量のAPIが存在する時にはとても重要
自動生成:なぜ?
• 以前github.com/nlopes/slackにPR送ったりしていたら
• ひとつの仕組みを直すのに20ファイルを手動で変更する
必要があった
Google(-ish) API
client.Chat().
PostMessage(channelID).
Text(“Hello, World!”).
Do(ctx)
Google(-ish) API
client.Chat().
PostMessage(channelID).
Text(“Hello, World!”).
Do(ctx)
まず「サービス」を取得じゃ!
サービスは論理的なグルーピングの
ことじゃな
Google(-ish) API
client.Chat().
PostMessage(channelID).
Text(“Hello, World!”).
Do(ctx)
メソッドを呼ぶための
「Callオブジェクト」を作成するぞ!
必須引数もここで指定じゃ。
Google(-ish) API
client.Chat().
PostMessage(channelID).
Text(“Hello, World!”).
Do(ctx)
Callオブジェクトに任意引数を
付与していくぞい。
Google(-ish) API
client.Chat().
PostMessage(channelID).
Text(“Hello, World!”).
Do(ctx)
最後にDoでようやく
リクエスト送信じゃ!
サーバー
• モックサーバー・プロキシサーバーを完全自動生成!
• Slackへの通信をインターセプト!
• ボットが無駄にポストしなくなる!
Previously…
development
instance
chat.postMessage
api.slack.com
Multiple
Messages
production
instance
chat.postMessage
slaproxy
development
instance
auth.test
api.slack.com
Only prod
production
instance
chat.postMessage
chat.postMessage
slaproxy
slaproxy
development
instance
auth.test
api.slack.com
Only prod
production
instance
chat.postMessage
chat.postMessage
slaproxy
副作用のないメソッド
だけ本番にパススルー
するんじゃ!
Kubernetesと相性良い!
• 本番Service (type=ExternalName, api.slack.com)
• 開発Service (type=ClusterIP, slaproxy Pod)
• どちらもクライアント側からは
slack.$namespace.svc.cluster.local に見える
コードジェネレーション
Goでコードジェネレーションしてる・したことある人?
手法は?
• ASTを作成して printer.Fprintf? (このドMがッ!)
• Perl/Python/Ruby/PHPから生成?
• text/templateで生成?
俺のおすすめ?
筋 肉
fmt.Fprintf
• schemalex/schemalex
• go-jsval
• go-libxml2
internal/cmd/gen*
• go-slack
• go-msgpack
• go-ical
• go-jsschema
拙作のライブラリではinternal以下にコマンドを
仕込んでおき、go generateから呼んでる
• schemalex/schemalex
• go-jsval
• go-libxml2
internal/cmd/gen*
• go-slack
• go-msgpack
• go-ical
• go-jsschema
拙作のライブラリではinternal以下にコマンドを
仕込んでおき、go generateから呼んでる
internal 以下なら
godocには載らないんじゃ!
endpoints.json
定義は適当なJSONファイルに放り込んである
go generate
あとは go generateから呼べるようにしておくだけ
go generate
あとは go generateから呼べるようにしておくだけ
サーバもクライアントも
同じ定義から作れるので
とっても便利じゃ!
.oO(こいつ、なんでテンプ
レート使わないんだろ…?
利点:ただのGoコード
• 他のGo資源を使える
• 分岐・再利用ブロックの制御が簡単
text/templateの限界に
挑戦する必要がない
• 「は!今のコンテキストからはグローバルな変数に直接アクセスできない…」
• 「あれ、この文字列を処理する関数をちょっと入れたいだけなのに… なに?
FuncMapだぁ?」
• 「補助関数・変数一杯いれたけど、一体今どれが有効なのかわからん!」
利点:
text/templateの限界に
挑戦する必要がない
• 「は!今のコンテキストからはグローバルな変数に直接アクセスできない…」
• 「あれ、この文字列を処理する関数をちょっと入れたいだけなのに… なに?
FuncMapだぁ?」
• 「補助関数・変数一杯いれたけど、一体今どれが有効なのかわからん!」
利点:
個人的には、簡単な
テンプレート以外で使う
text/templateはクソじゃと
思っておる!
利点:Goなら整形も簡単
• 改行だけ気をつけていれば細かいところは
format.Sourceが良きように計らってくれる
コードジェネレーション
Tips
筋 肉
Tip: Optionパターンが便利
• 任意の0~N個の引数を好きな順番で与える事ができる
• メソッドチェーンと同じく「メソッドの正しい引数の順
番」を考えるより楽
• 必須でない引数に便利
slack.New(
token, // 必須なので、Optionではない
slack.WithDebug(true), // デバッグ有効化
slack.WithClient(&http.Client{}), // http.Clientをカスタマイズしたい
)
Tip: メソッドチェーンは便利
• メソッドを呼ぶと、呼び出したオブジェクトを戻り値と
して返す
• メソッドの呼び出し順を(ほとんど)考えずに済む
•「メソッドの正しい引数の順番」を考えるより楽
slackClient.Chat(). // go-slackの場合…
PostMessage(…). // ここまでは必須。
Attachment(…). // ここから任意引数を…
EscapeText(false). // メソッドチェーン。
Do(ctx) // 最後にDo()を呼ぶと発火
Tip: メソッドは”.n”から
if (addMethod1) {
fmt.Fprintf(“.nMethod1()”)
}
if (addMethod2) {
fmt.Fprintf(“.nMethod2()”)
}
• 以下はパース失敗する
Foo()
.Method1()
.Method2()
• 以下はパース成功する
Foo().
Method1().
Method2()
Tip: メソッドは”.n”から
“n.” “.n”
Tip: 定義対象は必ずソートする
• 元々リストから生成するならやらなくてもOK
• マップから生成するクラス名、メソッド名、etc…
• 順番が安定しないと、diffがおかしなことになる
Tip: 無駄に思えても、1行ずつ
• 一気にPrint(複数行)とかしたくなるけど、我慢
• あとで何かを差し込みたくなったり、条件分岐する時に
そのほうが楽
Tip: 改行は最初に
• ブロックの開始を「予測」するより、ブロック開始時に2
個改行を入れるのが簡単
Tip: 生成されたファイル名を揃える
• 後悔するので、必ずファイル名から生成されたことがわ
かるようにしましょう
• “xxxxx_gen.go” 等で揃えるとよい
Tip: CIでgit diffをチェック
• 生成されたファイルがチャントコミットできてるか確認
• 結構漏れるので注意
• トラックされていないファイルは “git ls-files --
others —exclude-standard"
https://github.com/lestrrat/go-slack/blob/master/scripts/check-diff.sh
反省
決してわかりやすくは無い…
• 正直に言えば、コードジェネレータを「誰でも」読み解
けるかというと疑問が残る
• 必要な時だけ行うべき
それでもやるべき瞬間(とき)
• 今回のような機械的なコードの羅列がある場合
• そして、とにかくその数が多い
• 「自分がイチイチ変更していくと絶対エンバグするぞ」
という時
まとめ
fmt.Fprintfも結構使える
• テンプレートの書き方で悩むくらいなら、悩む時間
がもったい無いので筋肉で書けば良いのではないか
(言うほど難しくない)
• 慣れれば生成されたコードが心の眼で浮き上がって
くるようになります
おまけ
ジェネリックス?
• 欲しい時もあるけど、こういう時ではない
• 長年やってきて、凝縮されてエレガントなコードよ
り、機械的に量産できるシンプル・愚直なコードの
ほうが良い気がしてる
• というわけで今のGoでも充分

More Related Content

What's hot

AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
Takehiro Suemitsu
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
Kumazaki Hiroki
 

What's hot (20)

Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編Dockerfile を書くためのベストプラクティス解説編
Dockerfile を書くためのベストプラクティス解説編
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
AWSでAPI Gatewayから非同期でLambdaを起動してS3にファイルアップロードしようとしたらハマった話。
 
冬のLock free祭り safe
冬のLock free祭り safe冬のLock free祭り safe
冬のLock free祭り safe
 
マイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPCマイクロサービスバックエンドAPIのためのRESTとgRPC
マイクロサービスバックエンドAPIのためのRESTとgRPC
 
SQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するかSQL大量発行処理をいかにして高速化するか
SQL大量発行処理をいかにして高速化するか
 
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptxネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
DockerとPodmanの比較
DockerとPodmanの比較DockerとPodmanの比較
DockerとPodmanの比較
 
コンテナイメージの脆弱性スキャンについて
コンテナイメージの脆弱性スキャンについてコンテナイメージの脆弱性スキャンについて
コンテナイメージの脆弱性スキャンについて
 
最近のやられアプリを試してみた
最近のやられアプリを試してみた最近のやられアプリを試してみた
最近のやられアプリを試してみた
 
開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)開発速度が速い #とは(LayerX社内資料)
開発速度が速い #とは(LayerX社内資料)
 
Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版Dockerfileを改善するためのBest Practice 2019年版
Dockerfileを改善するためのBest Practice 2019年版
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
Go入門
Go入門Go入門
Go入門
 
忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?
 

Similar to 筋肉によるGoコードジェネレーション

Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
genroku
 
オープンセミナー香川2012 LT
オープンセミナー香川2012 LTオープンセミナー香川2012 LT
オープンセミナー香川2012 LT
Kouta Imanaka
 

Similar to 筋肉によるGoコードジェネレーション (20)

GitHub最新情報キャッチアップ 2023年6月
GitHub最新情報キャッチアップ 2023年6月GitHub最新情報キャッチアップ 2023年6月
GitHub最新情報キャッチアップ 2023年6月
 
Yapc2012資料
Yapc2012資料Yapc2012資料
Yapc2012資料
 
Gitlab meetup prm説明資料_2017_1117
Gitlab meetup prm説明資料_2017_1117Gitlab meetup prm説明資料_2017_1117
Gitlab meetup prm説明資料_2017_1117
 
今時のオンプレなgithubクローン環境構築
今時のオンプレなgithubクローン環境構築今時のオンプレなgithubクローン環境構築
今時のオンプレなgithubクローン環境構築
 
gitを使って、レポジトリの一部抽出forkしてみました
gitを使って、レポジトリの一部抽出forkしてみましたgitを使って、レポジトリの一部抽出forkしてみました
gitを使って、レポジトリの一部抽出forkしてみました
 
GitHub Copilotとともに次の開発体験へ
GitHub Copilotとともに次の開発体験へGitHub Copilotとともに次の開発体験へ
GitHub Copilotとともに次の開発体験へ
 
[Lt]versionごとにurlを自動生成
[Lt]versionごとにurlを自動生成[Lt]versionごとにurlを自動生成
[Lt]versionごとにurlを自動生成
 
Shizudev git hub宿題
Shizudev git hub宿題Shizudev git hub宿題
Shizudev git hub宿題
 
Programming AWS with Python
Programming AWS with Python  Programming AWS with Python
Programming AWS with Python
 
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
Webブラウザで使える文献Web API取得結果のスプレッドシート化 ~ Google Colab始めました ~
 
オープンセミナー香川2012 LT
オープンセミナー香川2012 LTオープンセミナー香川2012 LT
オープンセミナー香川2012 LT
 
Dropbox APIなどを使って制作を効率化しよう@関西オープンフォーラム
Dropbox APIなどを使って制作を効率化しよう@関西オープンフォーラムDropbox APIなどを使って制作を効率化しよう@関西オープンフォーラム
Dropbox APIなどを使って制作を効率化しよう@関西オープンフォーラム
 
Metahub for github
Metahub for githubMetahub for github
Metahub for github
 
20120827勉強会 webアプリ作ってみた2
20120827勉強会 webアプリ作ってみた220120827勉強会 webアプリ作ってみた2
20120827勉強会 webアプリ作ってみた2
 
Git & GitHub & kintone でウルトラハッピー!
Git & GitHub & kintone でウルトラハッピー!Git & GitHub & kintone でウルトラハッピー!
Git & GitHub & kintone でウルトラハッピー!
 
プログラミング支援AI GitHub Copilot すごいの話
プログラミング支援AI GitHub Copilot すごいの話プログラミング支援AI GitHub Copilot すごいの話
プログラミング支援AI GitHub Copilot すごいの話
 
GitHub Handson
GitHub HandsonGitHub Handson
GitHub Handson
 
CircleCIを使ったSpringBoot/GAEアプリ開発の効率化ノウハウ
CircleCIを使ったSpringBoot/GAEアプリ開発の効率化ノウハウCircleCIを使ったSpringBoot/GAEアプリ開発の効率化ノウハウ
CircleCIを使ったSpringBoot/GAEアプリ開発の効率化ノウハウ
 
oFの話題が殆ど出ない oF jp Summer Workout
oFの話題が殆ど出ない oF jp Summer WorkoutoFの話題が殆ど出ない oF jp Summer Workout
oFの話題が殆ど出ない oF jp Summer Workout
 
LINEにおける GitHub Enterpriseの活用事例と LINE Notifyについて
LINEにおける GitHub Enterpriseの活用事例と LINE NotifyについてLINEにおける GitHub Enterpriseの活用事例と LINE Notifyについて
LINEにおける GitHub Enterpriseの活用事例と LINE Notifyについて
 

More from lestrrat

More from lestrrat (20)

Future of Tech "Conferences"
Future of Tech "Conferences"Future of Tech "Conferences"
Future of Tech "Conferences"
 
ONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 WinterONIの世界 - ONIcon 2019 Winter
ONIの世界 - ONIcon 2019 Winter
 
Slicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPISlicing, Dicing, And Linting OpenAPI
Slicing, Dicing, And Linting OpenAPI
 
Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由Oxygen Not Includedをやるべき4つの理由
Oxygen Not Includedをやるべき4つの理由
 
Rejectcon 2018
Rejectcon 2018Rejectcon 2018
Rejectcon 2018
 
Builderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinnerBuilderscon tokyo 2018 speaker dinner
Builderscon tokyo 2018 speaker dinner
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
 
Google container builderと友だちになるまで
Google container builderと友だちになるまでGoogle container builderと友だちになるまで
Google container builderと友だちになるまで
 
iosdc 2017
iosdc 2017iosdc 2017
iosdc 2017
 
シュラスコの食べ方 超入門
シュラスコの食べ方 超入門シュラスコの食べ方 超入門
シュラスコの食べ方 超入門
 
OSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃないOSSの敵になるのもいいじゃない
OSSの敵になるのもいいじゃない
 
Coding in the context era
Coding in the context eraCoding in the context era
Coding in the context era
 
Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)Kubernetes in 30 minutes (2017/03/10)
Kubernetes in 30 minutes (2017/03/10)
 
Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016Opening: builderscon tokyo 2016
Opening: builderscon tokyo 2016
 
Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24Kubernetes in 20 minutes - HDE Monthly Technical Session 24
Kubernetes in 20 minutes - HDE Monthly Technical Session 24
 
小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016小規模でもGKE - DevFest Tokyo 2016
小規模でもGKE - DevFest Tokyo 2016
 
いまさら聞けないselectあれこれ
いまさら聞けないselectあれこれいまさら聞けないselectあれこれ
いまさら聞けないselectあれこれ
 
Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016Don't Use Reflect - Go 1.7 release party 2016
Don't Use Reflect - Go 1.7 release party 2016
 
How To Think In Go
How To Think In GoHow To Think In Go
How To Think In Go
 
On internationalcommunityrelations
On internationalcommunityrelationsOn internationalcommunityrelations
On internationalcommunityrelations
 

筋肉によるGoコードジェネレーション