Posts for: #2024/10

バドミントンの基本練習

今日のバドミントン練習は磯上体育館で9時から12時半頃まで3時間ほど練習できた。ひとりでリフティング練習をするよりも相手がいて打ち合いする方がずっと楽しい。午前中にしっかり動いたので2万歩を超えて昨日の消費エネルギーは4500カロリーを超えた。

体育館でバドミントン

前回の所感 。磯上体育館では月に2回ぐらい個人利用という先着順で予約できる仕組みがある。8時過ぎに磯上体育館へ行ったらすでに2組並んでいた。先頭の方は9時から2面予約するという。私は3番目で並んでいた。8時半頃には10人以上後ろに並んでいたので8時頃に行くと確実に予約できると思う。事務側も本当は9時から受付だけど、並んでいるせいか8時45分頃から予約受け付けしてれくた。こうやって予約を取るためにどんどん並ぶ時間が早くなっていくのかもしれない。

先頭に並んでいたシニアの方が気さくに周りに声をかけていて、話しているうちに仲良くなってその人たちの9時からの練習に混ぜてもらうことになった。ベテランのシニアな方で経験もあって教え方もとても上手だった。丁寧に教えてくれてすごく勉強になった。来週も個人利用で9時から借りると話されていたのを聞いて来週も練習に混ぜてもらうことにした。今日は3つの打ち方の基本を教えてもらいながら練習した。

  • クリア
    • コートの奥から相手のコート奥へ大きく前方へ打ち返す
  • ドロップ
    • クリアを同じ打ち方でコートの奥からネットを超えた前方位置へゆるく落とす
  • プッシュ
    • ネット前で浮いた球を下方に叩きつけるような打ち方になる

打ちながら、私のラケットの振り方や持ち方のよくないところを指摘してもらった。我流でやっていたからちゃんとした知識やフォームを教えてもらえるのは本当にありがたい。教えてもらったことで覚えていることを書いておく。

  • 足は肩幅に開いて準備をする
    • まだ言語化できないが、右足/左足の使い方について説明されてた
    • 足の親指部分にチカラを入れてコントロールするように話されていた
  • フットワークと足の位置を意識してみる
    • 私は無意識に一歩目は左足から動いてしまう
      • フォアハンドで打つときは右足から動いた方が速いのかもしれない
  • シャトルが来てから動くのではなく、来る前から位置を予測して動いて備える
  • ラケットを振るときに左手をあげてカラダのバランスをとる
    • 基本として左手をどう使うのかがすごく大事とのこと
    • 左手を下げない、肘を90度にまげてあげるのに備えておく
    • 手首をまげずに固定してラケットを振る
  • ラケットは親指と人差し指でつまむ気持ちで軽くもち、シャトルを打ち返す瞬間だけ握る
    • この感覚で打ち返すと真っ直ぐ強い打球を返せるようになった
    • バックハンドで返すときも同様でシャトルを打つ瞬間だけ握り込んで止めるような感覚で返す
  • 向かってくるシャトルに対してカラダの正面でとらえて打つ
    • この位置を固定にすることで安定して打ち返せる気がする

1時間ちょっと練習の指導をしてもらって30分ほどダブルスの試合をした。私は下手だからすぐ失敗してラリーが止まってしまう。試合形式になると簡単そうにみえるシャトルの打ち返しも緊張や前後左右の動きの中で失敗してしまう。練習でできないことは試合では絶対にできない。ラリーを止めてしまって他の人たちに悪いなと罪悪感を感じるし、練習する方がたくさんシャトルを打つことができて楽しい。もう少し上達するまでは試合は棄権しようかなとも思う。11時からいとうさんが来られて、前の時間帯に教えてもらった打ち方を意識しながらひたすら打ち合いの練習をしていた。その前の練習で教えてもらったことをゆっくり反復する時間をとれてこの時間もよかった。基本の打ち方を教えてもらった通りにやっていると狙ったところにうまく返せる回数が増えたように感じた。

ストレッチ

先週は実家へ帰ってストレッチをお休みして2週間ぶり。午前中にバドミントンの練習をたくさんして疲れていたのと、試合をしているときにころんで足と腰を少し痛めていた。その部位を伸ばす意図でもストレッチしてもらってちょうどよかった。運動して筋肉痛もある状態でストレッチするとよく伸びて、その日の睡眠もよく取れるし疲労回復も早くなる。今日の開脚幅は開始前146cmで、ストレッチ後155cmだった。ストレッチ前は筋肉痛で伸びないのがストレッチ後によく伸びていることが伺える。トレーナーさんはサッカーをずっとされていた方なのでたまたまはてブでみかけた町田ゼルビアの記事を話題にしたら盛り上がった。この著者の記事が3つもあがっているようにいまホット話題ではあるらしい。

ストレッチを終えて晩ご飯を食べた後にオフィスで作業しようと思っていたものの、家に帰ったら疲れてそのまま休んでしまった。体調が悪いわけでもないのに、最近はやらないといけないことをがんばる気力がなくなっている。なにか内からのやりたいが出てこない。

コンパクトな REALFORCE R1 キーボード

コンパクトな REALFORCE R1 キーボード

今日は午前中寝ていたのと雨降りだったのもありバドミントン練習はお休みした。

REALFORCE R1 レビュー

bluetooth の初回ペアリング設定を過去の R3 のペアリング設定 をみながら行った。手順を忘れていたのでまた書いておく。agent を介してパスキーを入力する必要がある。その手順が少しわかりにくい。30分ほどペアリング設定をうまくできなくてやり直ししたりしていた。滅多にやらないことだし。今回も GUI ツールではなく bluetoothctl を実行してペアリングした。

$ bluetoothctl
[REALFORCE_2 (R3)]# default-agent
Default agent request successful
[REALFORCE_2 (R3)]# scan on
Discovery started
... (デバイスを検索しているうちに RC1 がみつかる)
... MAC アドレスを確認してペアリングする

[REALFORCE_2 (R3)]# pair F7:62:4B:02:D6:EB
Attempting to pair with F7:62:4B:02:D6:EB  (キーボードに接続を試みる)
..
[agent] Passkey: 946185 (エージェントがパスキーを受け取る)
...

エージェントが受け取ったパスキーを、bluetooth 接続するキーボードで入力して Enter を押下する。

[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service000a
	00001801-0000-1000-8000-00805f9b34fb
	Generic Attribute Profile
[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service000b
	0000180a-0000-1000-8000-00805f9b34fb
	Device Information
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service000b/char000c
	00002a29-0000-1000-8000-00805f9b34fb
	Manufacturer Name String
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service000b/char000e
	00002a50-0000-1000-8000-00805f9b34fb
	PnP ID
[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service0010
	0000180f-0000-1000-8000-00805f9b34fb
	Battery Service
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service0010/char0011
	00002a19-0000-1000-8000-00805f9b34fb
	Battery Level
[NEW] Descriptor (Handle 0x0000)
	/org/bluez/hci0/dev_F7_62_4B_02_D6_EB/service0010/char0011/desc0013
	00002902-0000-1000-8000-00805f9b34fb
	Client Characteristic Configuration
[CHG] Device F7:62:4B:02:D6:EB UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device F7:62:4B:02:D6:EB UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device F7:62:4B:02:D6:EB UUIDs: 0000180a-0000-1000-8000-00805f9b34fb
[CHG] Device F7:62:4B:02:D6:EB UUIDs: 0000180f-0000-1000-8000-00805f9b34fb
[CHG] Device F7:62:4B:02:D6:EB UUIDs: 00001812-0000-1000-8000-00805f9b34fb
[CHG] Device F7:62:4B:02:D6:EB ServicesResolved: yes
[CHG] Device F7:62:4B:02:D6:EB Paired: yes
Pairing successful
[CHG] Device F7:62:4B:02:D6:EB Modalias: usb:v0853p031Ad0001
...
[REALFORCE_2 (R3)]# exit

ペアリングが成功したらキーボード入力できるようになる。bluetoothctl を eixt してから再実行すると今度は RC1 で実行された。

$ bluetoothctl
[RC1_1]# info
Device F7:62:4B:01:D6:EB (random)
	Name: RC1_1
	Alias: RC1_1
	Appearance: 0x03c1
	Icon: input-keyboard
	Paired: yes
	Trusted: no
	Blocked: no
	Connected: yes
	WakeAllowed: yes
	LegacyPairing: no
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
	UUID: Battery Service           (0000180f-0000-1000-8000-00805f9b34fb)
	UUID: Human Interface Device    (00001812-0000-1000-8000-00805f9b34fb)
	Modalias: usb:v0853p031Ad0001
	Battery Percentage: 0x5b (91)
[RC1_1]# trust 
[CHG] Device F7:62:4B:02:D6:EB Trusted: yes

この日記を R1 のキーボードで書いている。R3 と比べてたしかにコンパクトで軽い。キーボードを持ち運びするならよさそう。R3 と比べて右シフトキーが小さいのでその隣にある PgUp キーをタイプミスしてしまう。私は左右両方のシフトキーを使う。!記号などの左手でタイプするときは右シフトキーを使う。それからコンパクトサイズのせいか、キーとキーの隙間が若干狭くなったように感じる。矢印キーの位置もエンターキーの下の方に移動している。R3 の矢印キーの位置を無意識にタイプしようとして空打ちしてしまう。意外と矢印キーを私は使っていたことに気付く。これらの操作の違和感は慣れの問題だと思う。キーボードの打鍵感も R3 と比べて若干違う。気持ち、深さが増して軽い印象を受ける。キー荷重は 45g を選択した。R3 では変荷重モデルを使っていたので小指キーが 30g から 45g に変わる。その違いはあまり感じない。

キーボードは毎日たくさん使うものだから慣れによる無意識の最適化が自然と行われる。私の用途では R3 と R1 では右シフトキーと矢印キーの位置の違いに違和感を感じる。両方のキーボードを使い分けるというようにはならないのかもしれない。どちらかに慣れるともう一方に違和感を抱くように思える。

能楽の勉強

玄宗皇帝と楊貴妃の愛情物語の後日談《楊貴妃》 第41回能のことばを読んでみる会 に参加してきた。前回の所感はここ 。中国史上もっとも有名な美人といわれる 楊貴妃 の幽霊を主人公とした能になる。方士 と呼ばれる修行者が玄宗皇帝の命令で楊貴妃の魂魄の在り処を探していて蓬莱島でみつけて話しを聞くといった、とくに変わったこともない普通の物語の構成になっている。作者ははっきり分かっていないらしいが、世阿弥の娘婿になる金春禅竹 (こんぱる ぜんちく) ではないかと推定されるとのこと。

貴妃 というのは皇帝の后に与えられる位の1つで皇后に次ぐ高い位だという。楊が姓になる。唐の 玄宗皇帝 は在位期間が45年と長い。前半は善政をしいて唐は絶頂期を迎える。後半は楊貴妃にうつつを抜かすようになる。楊一族が政治の重要なポストを占めるようになり、玄宗皇帝が政治に関心をなくして最終的に反乱が起きて国が乱れてしまう。その後、白居易 (はくきょい) という著名な詩人が玄宗皇帝と楊貴妃の物語を 長恨歌 にした。この漢詩が素晴らしい内容だと評価されて後世にまで楊貴妃の物語が広く伝わる影響を与えたという。

源氏物語に出てくる 桐壺更衣 (光源氏の母) が楊貴妃のイメージや長恨歌から引用されて創作されているという。この能は源氏物語に出てくる長恨歌を引用した文章を引用して作られてもいて、伝言ゲームのように、引用を繰り返すうちに少しその内容が変わってしまうといったことも起きているらしい。おもしろかったのが、漢詩に序文をつけたりするのを詩序と呼ぶ。オリジナルの中国の長恨歌には詩序がないのに、日本に伝わって残っている長恨歌には詩序が残っていて、その詩序の内容を能でも引用していたりする。当時は長恨歌には詩序があったのに現代では失われてしまった可能性もないわけではないが、おそらく日本に伝わってきた後に誰かが詩序を追加したのではないかと考えられているらしい。

会者定離ぞと 聞く時は、逢うこそ別れなりけれ

以前 蝉丸の能 を読んだときにも 会者定離 (えしゃじょうり) が出てきた。一種の悟りのような表現だと朝原さんが解説していて私も記憶によく残っている。直接なにかの役に立つわけではないけれど、こういう言葉や概念に触れて自分の価値観をふりかえる機会があるのはおもしろい。能の言葉を読んでいるとそういう出会いがある。

exec とスクリプト

今日のバドミントン練習はエアシャトルでリフティングを60分した。連続最大回数は191回だった。もう少しで200回だったのに残念。木曜日は睡眠をたくさんとって疲れは少し取れたし、安定的に50回前後は続くようになりつつも、100回までに失敗してしまう。今日は100回を超えたのが2回だけだった。ラケットのスィートスポットでとらえたときにきれいに真上にあがる感覚が楽しい。うまくいくときは数回は続く。それが自然にできるときとそうじゃないときの違いを私は制御できてなくて言語化もできない。

エアシャトルとメイビスにおけるリフティングの違いを比べてみると、メイビスの方が打ち上げて落ちてくるときにあまり回転せずコルクが下を向く傾向が多いようにみえる。エアシャトルの方がコルクが重い分、縦方向に回転し始めるとその回転が止まらず、回転しているからラケット面でとらえるのが難しくなる。だからエアシャトルの方がメイビスよりもリフティングが難しいといえる。シャトルを高く打ち上げると、落下してくる距離が長くなりその回転が落ち着く傾向があるからリフティングしやすくなるのではないかと仮説を考えた。伸び悩みかもしれないし、地道に練習を継続するときかもしれない。

exec とエントリーポイントのスクリプト

コンテナを起動して stop すると SIGTERM が送られる。そのときに api サーバーでシグナルの処理をしているのに、気付いたらシグナル処理が行われずタイムアウトするようになっていた。デフォルトでは10秒でタイムアウトして強制終了となる。なぜシグナルを捕捉しなくなったかを調査したら、あるときサーバーの起動前に前処理が必要になってエントリーポイントをシェルスクリプトにしていた。そのときに exec しないと、シェルスクリプトのプロセスに対してシグナルが送られるため、api サーバーがシグナルを検知できなくなるという副作用があることに気付いた。これまでも exec を使うとプロセス ID は変更されないという知識を知っていたが、それがどういう状況で役に立つかを理解できていなかった。シグナルを用いた同期処理に exec が役に立つ状況があることを学んだ。修正は次の1行のみ。

--- a/docker/entrypoint.sh
+++ b/docker/entrypoint.sh
@@ -2,4 +2,4 @@
 ...
 ... (pre process)
 ...
-./bin/api "$@"
+exec ./bin/api "$@"

go test からバイナリをビルドしてサーバーを起動する

先日 結合テスト向けカバレッジ計測の調査 をした成果を使って実際に go test からカバレッジ計測のカスタマイズを施したバイナリをビルドしてサーバー起動するコードを書いてみた。やや手間取ったが、一通り動いてカバレッジを計測できた。例えば、単体テストのカバレッジを計測するための makefile のターゲットは次のようになる。

GO_COVER_DIR:=$(CURDIR)/tests/coverage

coverage:
	@mkdir -p $(GO_COVER_DIR)
	go test -tags=integration -race -cover ./... -covermode atomic -args -test.gocoverdir=$(GO_COVER_DIR)

go は fork ができない。fork の代わりに exec を使う。How do I fork a go process? に go の goroutine のスケジューリングと fork は相性が悪くてうまく動かないということが背景だと説明されている。それはともかく exec を使ってもサーバープロセスを非同期に起動できたのでそのスニペットを書いておく。

binaryPath, err := buildBinary()
if err != nil {
	return 1
}
args := []string{
	"-verbose",
	"-port",
	strconv.Itoa(ServerPort),
}

r, w := io.Pipe()
go func() {
	s := bufio.NewScanner(r)
	for s.Scan() {
		fmt.Println(s.Text())
	}
}()

cmd := exec.Command(binaryPath, args...)
cmd.Stdout = w
if err := cmd.Start(); err != nil {
	slog.Error("failed to start api server", "err", err)
	return 1
}
defer func() {
	if err := cmd.Process.Signal(syscall.SIGTERM); err != nil {
		slog.Error("failed to terminate the api process", "err", err)
	}
	if s, err := cmd.Process.Wait(); err != nil {
		slog.Error("failed to wait terminating the api process", "err", err)
	} else {
        w.Close()
		slog.Info("completed to terminate the api process", "s", s.String())
	}
}()

// サーバーに対するテストを実行

サーバープロセスの標準出力のログを io.Pipe を使って出力することもできる。exec で生成したプロセスに対してもシグナルを送ったり終了を待つこともできる。デバッグしている分にはこれで意図したように制御できた。この知見は将来的に役に立つ気がする。0時過ぎから調査を再開して4時前ぐらいまでやっていた。少しはまって時間はかかったものの、久しぶりに集中してデバッグしていた。

変な疲れかた

今日のバドミントン練習はエアシャトルでリフティングを40分した。連続最大回数は168回だった。いくつか練習場所を転々としながら最終的にはホームのビルの軒下に行き着いた。環境のよい場所を知ってしまうと、それよりも劣る環境で練習することに抵抗を感じてしまう。昼間なら風がなくて人通りの少ないところであればどこでもそう大差はないが、夜は証明と背景でシャトル視認性 が変わってくる。21時まではホームのビルで、21時以降はその隣のビルでといった定番の練習場所ができつつある。今日はなんとなく調子がよくなくて練習していて手応えや集中力を感じなかった。

午前中に結合テスト改善に関するドキュメントを書いて、お昼から rpm パッケージングのリファクタリングやって、夕方に午前中に書いたドキュメントを使いながらメンバーに結合テスト改善の要項について共有した。そして17時半にはお仕事終えて帰った。晩ご飯も外食してリフティング練習も早めに切り上げて帰った。ここ数日あまり睡眠時間を取れていなかったのもあり、疲れているかも?と21時過ぎから横になって寝ていた。

テストライブラリの導入

今日のバドミントン練習はエアシャトルでリフティングを25分した。連続最大回数は277回できた。初めてエアシャトルで200回を超えた。しかも夜なのに。やや高めに打ち上げれば安定的にリフティングできるようになってきた。連続回数が増えることはラケットとシャトルの距離感、ラケットコントロールが上達していることの証左でもあるので200回を超えたときは嬉しかった。

テストライブラリの追加

結合テストを改善するために2つのライブラリを新たに使うよう導入した。

testify は名前だけ知っていたが、実際に使ってみるのは初めて。testify は大きく3つの機能もっている。

  • アサーション
  • テストスィート
  • モック

うちらのチームで使うのはアサーション機能だけになる。モックも将来的に使う可能性はある。アサーションを使うと自分でエラーメッセージを書く手間を省ける。次のようなコードがあった場合、

if expected != actual {
    t.Errorf("expected %d, but got %d", expected, actual)
    return
}

次のようにエラーレポートを testify に委譲できる。このぐらいの利便性でしかないが、テストの規模が大きくなったり、量が増えていけば読み書きのコストを削減できるかもしれない。

if !assert.Equal(expected, actual) {
    return
}

httpexpect はまったく知らなくて初めて使ってみたが、感触がよい。これもデフォルトのエラーレポート機能は testify のアサーション機能を使っているようにみえる。これまでは http リクエストに対して自前のユーティリティ関数と組み合わせて次のようなコードを書いていた。

res, err := doHTTPRequest(body, UserPath, http.MethodGet, "")
if res.StatusCode != http.StatusOK {
    t.Errorf("expected to get %d, but got %d", http.StatusOK, res.StatusCode)
    return
}
var actual entry.User
if err := convertBody(res, &actual); err != nil {
    t.Errorf("failed to convert: %s", err)
    return
}

httpexpect を使うと次のように簡潔に記述できる上にエラーレポートを httpexpect に委譲できる。これはかなりテストコードを読み書きする工数を削減できると思う。

var actual entry.User
e.GET(UserPath).
    WithJSON(map[string]any{ ... }).
    Expect().
    Status(http.StatusOK).
    JSON().
    Decode(&actual)

mongodb のテストデータ管理

今日のバドミントン練習はエアシャトルでリフティングを45分した。連続最大回数は146回できた。調子は悪くなく安定的に30回前後は続くものの、50回を超えたぐらいで失敗してしまう。打ち上げる高さの違いかな?と気付いて少し高めに打ち上げるようにしたら100回を超えた。エアシャトルはラケット面に対して適切な角度でコルクを打たないとあらぬ方向に飛んでいってしまう。高く打ち上げるほど、重力で落ちてくるときにコルクが下を向きやすくなるため、うまくシャトルを打ち上げやすくなる。ラケットコントロールをうまくできれば、エアシャトルをより低い高さでリフティングできるようになるかもしれない。まだ私はそのレベルには満たない。

json からの mongodb にテストデータを追加する

結合テストの改善をしていてテストデータを json で管理したい。これまで go の構造体でテストデータを定義して mongodb の client で insert するといったことをしていた。それも役に立つのだけど、共有のテストデータがどこにあるのか、ソースコードに書いてしまうと時間とともに散らばっていって把握できなくなっていく。テストデータを管理するためのディレクトリを設け、そこに json で記述してどのテスト関数で使うかといったメタ情報も定義できるようにした。次のコードは mongodb に json からデータをインポートするための原理を説明するための疑似コードのようなもの。

go の構造体で定義したテストデータと json で管理するのとどちらがよいかというのは議論の余地はあるし、一概に言えないとは思う。

type testData struct {
	Documents    []bson.Raw `bson:"documents"`
}

func InsertData(
	t *testing.T, client *mongo.Client, b []byte,
) (func()) {
	var data testData
    err := bson.UnmarshalExtJSON(b, false, &data)
	require.NoError(t, err, "failed to get json files: %v", err)

	ctx := context.Background()
	col := client.Database(dbName).Collection("mycollection")
	r, err := col.InsertMany(ctx, docsToInterfaces(data.Documents...))
	require.NoError(t, err, "failed to insert: %v", err)

	return insertResult, func() {
		t.Helper()
	    col := client.Database(dbName).Collection("mycollection")
		for _, id := range r.InsertedIDs {
			filter := bson.D{{Key: "_id", Value: id}}
			if _, err := col.DeleteOne(ctx, filter); err != nil {
				t.Errorf("failed to delete %s: %v", id, err)
				return
			}
		}
	}
}

呼び出し側のイメージ。defer で teardown を呼ぶことでテスト完了時に追加したテストデータを削除してくれる。

teardown := mongotest.InsertData(t, mongoClient, b)
defer teardown()

...

bson.Raw として読み込める json データは bson パッケージのユーティリティを使って dump できる。

func dumpAsJSON(value any) {
	b, err := bson.MarshalExtJSON(value, false, false)
	if err != nil {
		slog.Error("failed to marshal as extended JSON", "err", err)
		return
	}
	fmt.Println(string(b))
}

バドミントンのセンスは距離感らしい

バドミントンのセンスは距離感らしい

今日のバドミントン練習はエアシャトルでリフティングを110分 (エア110分) した。1回あたりは20-30分で休憩する。最大連続回数は192回だった。もうちょっとで200回を越せそう。

ラケットとシャトルの距離感の考察

エアシャトルでリフティングをしていると、きれいに真上にあげられるときとシャトルにスピンがかかってしまうときがある。スピンしてしまうと、ラケットのスィートスポットでコルクをとらえるのが難しくなる。試しにエアシャトルをラケット面に並べてみた。中心部でシャトル3つ分の横幅しかない。この中心部分でラケットのコルクをとらえるとうまく弾ける。シャトルが回転していると、コルクが垂直方向から傾いた角度でラケット面に当たったりフレームに当たる確率が高くなる。ラケットの上部だとシャトル2つ分の横幅しかない。リフティングを失敗してしまうのは回転中のシャトルをはたいたり、あらぬ方向へ飛ばしてしまうことが多い。うまくラケットコントロールを行い、なるべくシャトルをスピンさせずに上げることができればリフティングが安定する。

今日は昼間と夜間にビルの軒下で練習した。風の影響も軽微だったので安定的に連続して50回前後はできていたと思う。121, 146, 192, 152, 122, 106, 102, 120 と連続して100回を越せたのが8回もあった。うち2回は夜になる。メビウスだと100回に1-2回ラケットコントロールをミスしてシャトルをうまく上げられないときがある。そのときにリカバリをうまくやれば続けられる。安定的に100回程度のリフティングができるからリカバリを連続で2-4回できれば200回を超える。この原理はエアシャトルも同様になる。仮にエアシャトルだと20回に1回うまく上げられないとする。200回を超すには連続で10回リカバリできないといけない。リカバリできるかどうかは運の要素もある。回転しているシャトルがフレームのどこに当たるかでリカバリ可能な場合とそうではない場合がある。10回連続でリカバリするよりも5回連続の方が、5回連続よりも2回連続の方が容易な状況と言える。つまり、ラケットコントロールが上達するとリフティングにおけるシャトル打ち上げのミスが減る。ミスが減るとリカバリ試行の回数が減る。リカバリ試行の回数が減ると連続回数が増えるという理屈になる。

今日エアシャトルで192回連続で続いたことはたまたまリカバリが連続的に成功した結果であり、リカバリを必要とせず安定的にどれだけ長くリフティングを続けられるかの方が重要ではある。よいときのラケットコントロールの感触を覚えておいて再現できるように努めていく。

次の動画によると、バドミントンのセンスとは「距離感」とのこと。練習しているうちに距離感は少しずつよくなる。そして速いプレーになると距離感をつかむのはもっと難しいとのこと。

距離感をつかむための練習としては次になる。私がいまひとり練習しているのはまさにこれになる。

  • シャトルのキャッチ
  • シャトルのリフティング
  • 一人でロビングを打ってみる

2人いればシャトルパスもおすすめとのこと。

中学校体育館の夜間開放

バドミントンができる体育館探し。抽選予約のためのアカウント登録 を終えて初めての抽選。15日ゼロ時に抽選が行われる。初回なので0時頃に待機してみていた。本当に0時まわってから抽選のバッチ処理が動いているようでサイトで更新していると2-3分後に抽選結果が表示されるようになった。最大4つ抽選申し込みできる。残念ながらすべて落選だった。15日以降は先着順で予約できる。抽選結果が出た後も空きがあれば先着で校区以外の中学校も予約できる。校区以外の夜間開放されている中学校のうち、私が住んでいるところから近い区で駅から徒歩10-15分程度で歩いていけそうな中学校をピックアップしてみた。

灘区

  • 原田中学校

中央区

  • 渚中学校

兵庫区

  • 兵庫中学校
  • 湊川中学校
  • 須佐野中学校

長田区

  • 駒ケ林中学校
  • 長田中学校

予想した通り、抽選確定後にみんな先着申し込みを検索しているらしく断続的に 504 エラーが出たりもしていた。私が検索して確認できた中では渚中学校と須佐野中学校に先着の空き枠が1つ2つあった。他の中学校はすべて埋まっていた。空きがある中学校もあるんだなと検索してみているうちに0時10分までにはそれらも誰かに先着予約されたみたいで埋まっていた。14日の深夜 (15日ゼロ時過ぎ) に街中の駅からアクセスのよい中学校の予約はすべて埋まると考えてよさそう。中学校によって貸し出し可能な日が平日/休日ともにあるところもあれば週末だけのところもある。11月はどこの体育館も予約できなかったが、今回は抽選申し込みと先着申し込みの雰囲気を把握できた。

田んぼの畝作り

今日のバドミントン練習は主にエアシャトルでリフティングを80分 (メイビス10分、エア70分) した。今日の連続最大回数は79回だった。メイビスなら10分以内に200回は続けられるようになってきた。ウォームアップにメイビスでリフティングを始める。今日は5回目ぐらいで250回続いた。リフティング練習を1時間もやれば1日の消費エネルギーは3,000カロリーを超える。

田んぼの宿題

8月に実家に帰って田んぼを耕した が、土がよく乾いていて畝を作れるような状態ではなかった。その後、雨を待って土が適度に水分を含む状態になるのを待っていた。帰れるタイミングもあって今日になった。前回から約2ヶ月たつとまた雑草が茂り始めていたところだった。雑草を駆除するだけでも3ヶ月に1回ぐらいの頻度で田んぼを耕さないといけない。昨日の夜から帰っていたため、朝7時半ぐらいからトラクターで耕し始めて11時頃には畝作りも終えた。

いずれコワーキングスペースで農業体験を始めたらトラクターで田んぼを耕すのもメニューに組み込みたい。多くの人はトラクターになんか乗ったことないだろうから1度はやってみたいと思う。3ヶ月に1回は雑草駆除のために耕した方がよい。気軽に縦横無尽に田んぼを耕せる機会を提供しやすい。

その後、粗大ごみを市の処分センターにもって行ってお昼ご飯食べてから帰途につく。

いつもと違う帰り道

先日の 毎日1つ新しいことを試して変化を楽しむ という学びを思い出したのと、時間に余裕があったからいつもと違う道を通ってみようと、明石海峡大橋を渡って垂水ジャンクションから降りて海岸線の下道を走りながら帰ってきた。垂水ジャンクションの出口は山側になるのでそこから海岸線までわりと距離がある。海岸線に下るのに20分ほどかかる。垂水から須磨の海岸線はそんなに混雑しないので下道でもそれほど時間はかからない。10分ぐらいかな。その後、若宮からまた阪神高速に乗る。湊川IC付近は常に渋滞する というのも知った上で軽い渋滞なら高速の方が早いだろうと予測した。やはり渋滞はしていたものの、それでも時速20-30kmで流れている程度の軽微な渋滞だったので20-30分で若宮-京橋間を走って帰宅した。垂水ジャンクションを降りずにそのまま高速道路を走るよりもずっと時間はかかっているのだけど、知らない道を走るというのも気分転換にはなる。

バドミントンの練習

ダイソーでベルトにひっかけるポーチ (300円) とベルト (100円) を購入した。エアシャトル も9個購入した。このポーチにシャトルを10個ほど詰めて、こまめにシャトルを拾わなくても効率よく練習できるようにした。

夕方から磯上公園でリフティングをしていたが、いまひとつ続かない。調子が悪い。田んぼ作業で疲れているせい?暗くなったので場所を変える。旧居留地にある新しい練習場所としてワイズロードの近くや三井住友銀行神戸本部ビルの前とか、転々としながら試してみたがいまいち。その後、バスの営業所の駐車場へ行った。まぁまぁできたが、風がやや吹いているのが気になって、次にみなとのもり公園へ行ってみたが、そこはもっと風が強くてリフティングできる環境ではなかった。最後に サンボーホール のビルへ行ってみた。前から試してみたいと思っていた。このビル前の広場も休日の昼間は子ども連れの家族がよく遊んでいる。日曜日の22時には誰もいない。

磯上公園よりもバスの営業所よりも風の影響が小さくてとてもよかった。この場所で20分ほどエアシャトルでリフティングして安定的に20-30回をこなすことができた。最高は79回と過去最高ではないが、3回以上は連続50回を越した気がするので練習をしてしての感触は悪くなかった。そこでエアシャトルのリフティングは風の影響を受けやすいことに気付いた。エアシャトルを安定的にリフティングをするにはメイビスよりも高く打ち上げないといけない。しかし、高く打ち上げるほど風による影響を受けやすい。そよ風がふくだけでも軌道がずれる。シャトルが落ちてくる位置を目視しつつ予測しつつラケットコントロールをする。しかし、ちょっと風が吹くだけで微妙にズレてしまい、ラケットのフレームなどに当ててしまう。昼よりも夜の方が暗いから風の影響による補正が難しい。サンボーホールがもっとも風が弱くてリフティングが安定することに気付いた。そして、この場所は日曜日の夜でも照明がついている。

ホームのビル はオフィスビルのせいか、休日は消灯している。これまで休日の夜に練習する安定的な場所がなかった。だから休日は公園で明るい時間帯に練習してきた。しかし、サンボーホールが休日でも照明がついていて風の影響を受けにくい構造なら休日の夜の練習場所になるかもしれない。偶然よい場所をみつけた。

照明の明るさや色合いとシャトル視認の考察

今日のバドミントン練習も引き続き主にエアシャトルでリフティングを70分 (駐車場10分、公園35分、ビル25分) した。土曜日なので昼間に駐車場や公園、ビルの軒下で練習した。20-30分もやれば集中力が途切れてくるので休憩と気分転換を兼ねて場所を移動している。今日の連続最大回数は122回だった。安定的に20-30回は続くようになってきた。メイビスフィールドだと10分やれば1度は200回以上続けられる程度に安定してきた。

エアシャトルのコルクが真下を向いているときにラケットのスィートスポットでとらえるとうまく上がる。失敗するときはラケットコントロールを誤ってシャトルを回転させてしまうことが多い。エアシャトルはコルクをラケットのガットでとらえないとうまく上がらない。回転しているとシャトルの裾をはたいたりコルクをフレームに当てて跳ね上がらなかったり、跳ね上がってもあらぬ方向へ飛んでいってしまう。軽い失敗で回転させてしまっても、ちょっと強めに打ち上げると重力で補正されてコルクが真下を向くように修正できるときがある。そのリカバリがうまくいくと連続回数が増えていく。

練習場所と照明と背景の考察

近所にバスの営業所があり、その駐車場が広くて明るかったので練習してみた。ここは24時まで照明がついている。周りは大きなマンションまたはビルに囲まれている。平日の22時台で20分ほど練習していたが誰も来なかった。広くて周りに気を遣う必要もなくシャトルも視認しやすかった。また今度行ってみようと思う。

先の駐車場の印象がよかったので広い駐車場なら練習しやすいのかな?と思って別のところへも行ってみた。基本的に駐車場は24時間照明がついていて明るいところが多い。しかし、駐車場ならどこでもいいわけでもなかった。次の駐車場はシャトルの背景が複数のビルと夜の闇で移り変わってしまい、背景の明るさが変わる影響でシャトルを視認しにくいことに気付いた。広くて明るければどこでも練習しやすいわけではないことに気付いた。

次に電球色なら昼白色の照明よりも目にやさしいから練習しやすいのではないかと考えた。旧居留地の有名な建物の隣のビル。写真ではわかりにくいが、次のビルの照明は橙色の電球色になる。試してみたら意外とシャトルを視認できなかった。その理由はシャトルの色が昼白色に映える赤色や黄色に着色されているため、電球色に照明に溶け込んでしまってシャトルそのものを視認しにくくなってしまうように思えた。もしかしたら白いシャトルなら逆にみやすいのかもしれない。今度また試してみる。

夜にバドミントンの練習をする場所探しで大事な要素がいくつかわかってきた。一見、明るさだけをみてよさそうに思えてもシャトルを使ってリフティングしてみると視認しにくい場合がある。実際に試さないとその場所がよいかどうかはわからない。今回の調査から考察したことをまとめる。

  • 照明の明るさと色
    • 暗すぎたらみえない
    • スペース全体が明るくてもシャトルを視認しやすいとはかぎらない
    • 照明が明る過ぎても眩しい
      • 照明がそれほど強力ではなくても目と照明との距離が近いと眩しい
      • 屋根の高いビルの軒下の視認性が高いのは目と照明との距離が遠いからだと気付いた
    • 電球色だと赤/黄色のシャトルを視認しにくい
  • 視界における背景色とシャトルとのコンストラクト
    • シャトルを目で追うときに背景の明るさや色が変わると視認しにくい
      • 背景が変わらない場所の方がその背景色に目が慣れてシャトルを視認しやすくなる
        • ビルの軒下の視認性が高いのはビルからみえる壁や背景が一様だから
  • スペースの広さ
    • 近くに壁や垣根、屋根があると避けようとして注意力を取られる
    • 周りに人が来ないことがわかっている場所の方が集中できる
      • 駐車場は断続的に車や人が来るので集中しにくい
    • 広い方が照明との距離を調整しやすい
    • 周りの背景があまり変わらない殺風景な場所の方がシャトルを視認しやすい

1日ひとつだけ、強くなる

昨日 はらさんに紹介してもらった梅原大吾の著書 の目次を眺めていくつか気になったところを読んでみた。1つの項目が2-3ページぐらいなのでタイトルで気になったところをすぐ読める。全体の3割ぐらいしか読んでいないけれど、それでも私には役に立ったので所感をブクログに書いてみた。

「格闘ゲーマーだって、正直飽きる」というタイトルがあってモチベーションコントロールについての梅原さんの考え方を読むことができた。私もプログラミングは好きだが、かといって飽きやマンネリがないわけではない。

この義務感というのは結構な曲者だ。時折「仕事でもないのに、そんな真剣にやってられるかよ」という人がいる。これは逆ではないだろうか。仕事が持つ義務感によって、かえって向上心を持つことが難しくなることは多い。義務感によってやらされているという、受け身の状態になってしまう。これが進行すると「最低限の基準さえ保っておけばそれでいいだろう」といた気持ちにまでなりかねない。

義務感によって受け身にならないこと。受け身というのは、外部からの刺激に依存したやり方だ。刺激を与えられている間はいいけれど、それがなくなればやる気もなくなる。

この悩みがあるときにひとりだと自分に言い訳をしてすぐ受け身の状態になってしまう。常に新しい取り組みや変化への挑戦をしていかないと、人間は怠惰で最低限の基準で受け身になってしまう。いまの私には耳の痛い話しでもある。そして、梅原さんの考え方を読んでいても、結局のところ、この状態を抜け出すにはモチベーションにとらわれない継続の仕組みを自分で見出すだけのように読めた。

評価してもらえない内的な成長を、どれだけ意識できるかで、モチベーションは大きく変わってくる。

プロであれアマチュアであれ、やるべきことは結局ほとんど変わらない。僕は、少しずつ自分のペースを取り戻していった。何か打ち込んでいることや、続けていることがあるのなら、成長のループを継続することを考えてほしい。毎日の歩みがいかにわずかであっても、安定した継続というのはそれだけで自信になるからだ。

本書のタイトルにもなっている「1日ひとつだけ」という言葉の背景として、梅原さんは1日を思い返して自身の成長を1つだけメモしているという。日記を書くことの意義とも共通する。日記の意義の1つはふりかえりを自然に行っていることになる。そして、外からみてわからない内的な成長を自分で気付いて成長を実感したり、自身の基準で肯定することが継続のためのモチベーションコントロールによいと梅原さんは実践している。この考え方は私が日記を3年書き続けていることから得た気付きとも合致する。よい時期によい本と出会えた。

実家へ帰る

先日トラクターで 真夏の硬い田んぼ を耕すのはやりにくかった。雨が降って適度に乾いた状態の田んぼを耕すために実家へ帰る。今日は親が外出しているというので20時から帰って明日、田んぼ作業をすることにした。

ひとりではできないこと

今日のバドミントン練習はエアシャトルでリフティングを30分した。連続最大回数は80回だが、ほとんどの試行は20回も続かずに失敗してしまう。難しい。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日の議題はこれら。

課題管理と adr の関係の考察

数年前から adr の話題や導入した会社の記事などをみかけるようになった。私はこれまで課題管理をうまくやっていれば adr はそれほど重要ではないとあまり重視してこなかった。しかし、世の中的に認知されて流行っているものはなにかしら意義があるのだろうと最近は少し見直してきているところもある。このスライドによると2017年から流行り始めたらしい。

  • 開発に関する情報を一元管理する、または全文検索ことにビジネスチャンスはある
    • 検索のニーズや要件は多様で言語によっても違い、技術もまだまだ発展的でもあるからずっとビジネスの種になる気はする
    • gitlab issues のコメントの全文検索は有料機能なので slack 通知したチャンネルを全文検索している
      • 課題管理システムのプラグインでテキストをシステム間連携することで検索システムを別途構築できる可能性がある
      • 検索できなくてもデータのアーカイブをするという視点でもビジネスニーズに応える?
  • ベクトル検索 を検索がまだ一般的にはなっていない?
  • wiki と adr の違いの1つとして wiki になにを書いてよいかわからない問題がある
    • 文章を書けるようになるのは経験や習熟を必要とする
    • adr のようなテンプレートがあることで経験の浅い開発者も書きやすくなる狙いはある
    • 課題管理システムの wiki に adr のラッピングをして別機能としてみせるのはよいかもしれない
    • 業務の引き継ぎにも adr は役に立つのではないか?
    • adr 一覧をみたり、そこから検索することで検索効率や精度は上がるという想定
  • 大きい会社でも巨大な課題管理システムと wiki が1つだけあって一元管理しているという噂は聞く
    • ある会社では wiki は誤っている可能性があるから信用するなという教訓があった
      • wiki の情報は更新されていない可能性があるから参考にしながら必ず裏をとって業務をしなさいという話し
    • wiki を編集したら必ずレビューが必要になるプロセス
  • notion のプロジェクト管理の使い勝手はどうか?
    • テンプレートを使ってガントチャートやカンバンを作れる
      • 基本的に自分でカスタマイズできることの良し悪しがある
        • db をどんどん改良できるが、それだけに魔改造してしまう
        • 時間とともに複数人が改良すると保守できなくなっていく懸念がある
      • 中核機能をパッケージ側で提供することは堅牢性を担保する上で重要ではないか
    • タスク管理と wiki がシームレスなところはよい、はらさんは日報を書いてリンクしている
  • 会社のインフラに日々の開発情報を書いていくと退職後に参照できない
    • フリーランスのような働き方をするにはナレッジデータベースをローカルに作りたいという欲求がある
    • 組み込みの課題管理システムにより、自身のナレッジデータベースをローカルに残すという目的はよいかもしれない

仕事は楽しいかね? の考察

まとめを見返しながら、だいたいの項目は理解または支持できる。1つだけ次の項目が私には欠けていることに気付いた。

毎日1つ試し続ければ必ず上達や進歩ができる

  • 新しいことを始めると、いまやっていることを継続する時間がなくなったりしないか?
  • プロダクト開発ではがんばってもあまり成果が出ないような時期もある
    • リファクタリングやテスト追加などはまさにそう
    • そういったときも1つでも変化をもたらせれば日々の生活が変わるのか?
  • はらさんのお奨めは梅原さんの 1日ひとつだけ、強くなる。 世界一プロ・ゲーマーの勝ち続ける64の流儀
  • 本書を読んではらさんのよかったところは「試してみることに失敗はない」
    • それまでも試すことはやっていたはずなのに躊躇してしまう理由として失敗したら時間の無駄だと考えてしまっていた
    • 失敗したら嫌だと考えてしまうところがあったが、この考え方があるから vision pro を購入できる
    • やりたいことをすぐやってみるという思考につながった
  • 面倒くさいときもなるべくパソコンを使うようにしてなにかしら調べる
  • 私はオフィスにいれば、家よりはなにかしら作業するモチベーションになる
  • 目標達成や成果をあげるには環境がもっとも大事
    • 個人の感情を信頼しない
      • 人間は面倒だとすぐ怠けてやめてしまう
    • 環境を整えることでワークフローを洗練させて習慣化する
      • 日記になにか書かないといけないから調べものをする
      • 嫌々ながらでもやっているうちに習慣になってくるとワークフローが洗練していく
      • 人間の運用を変えていくなにかは普遍的な価値またはビジネスチャンスがある
    • 調子の悪いときにどうやって早く脱却するかが大事
      • ひとりでは言い訳を作ったり怠けてしまう
      • このときに他人の助けがいるのではないか?
        • 話しを聞いてもらうだけでも前へ進むきっかけになる

go の結合テスト向けカバレッジ計測の考察

以前リリースパーティーで go 1.20 で結合テスト向けのカバレッジ計測の機能が入ったことを聞いていた。次のブログ記事でやり方が紹介されている。

将来的に結合テストを作るときにカバレッジ計測のカスタマイズを施したバイナリを使って api server を起動する仕組みにすればこの機能を使えることに気付いた。

まずは単体テストを実行して任意のディレクトリ (tests/coverage) にカバレッジ計測のための中間データを生成する。

$ mkdir -p tests/coverage
$ go test -cover ./... -covermode atomic -args -test.gocoverdir="$PWD/tests/coverage"
$ go tool covdata textfmt -i=./tests/coverage -o coverage.out

coverage.out がさまざまなツールの入力となる統計情報となる。例えば、このファイルを使って次のようにしてソースコードのヒートマップの html を作成できる。

$ go tool cover -html coverage.out -o coverage.html

nikolaydubina/go-cover-treemap を使うと treemap でカバレッジのヒートマップを確認できる。

$ go-cover-treemap -coverprofile coverage.out > treemap.svg

カバレッジ計測向けのバイナリをビルドする。そのバイナリを起動するときに環境変数 GOCOVERDIR に単体テストのカバレッジの中間データが含まれるディレクトリを指定する。

$ go build -cover -covermode atomic -o bin/api ./cmd/api/...
$ GOCOVERDIR="$PWD/tests/coverage" ./bin/api -verbose

このバイナリを使って起動した api server に対してリクエストを呼び出すことでカバレッジを計測してくれる。結合テストからバイナリ起動した api server に対してリクエストしたときに GOCOVERDIR に中間データが追加されていく。結合テストを完了したら最終的なカバレッジの統計情報を生成する。 

$ go tool covdata textfmt -i=./tests/coverage -o coverage.out

textfmt のヘルプをみたら同じディレクトリじゃなくてもよいみたい。

$ go tool covdata textfmt -help
...
Examples:

  go tool covdata textfmt -i=dir1,dir2 -o=out.txt

  	merges data from input directories dir1+dir2
  	and emits text format into file 'out.txt'

練習場所のビル探し

今日のバドミントン練習はリフティングを昼夜あわせて85分 (メイビスで75分、エアで10分) した。フォア持ちとバック持ちを交互に切り替えリフティングで398回続けられた。目標の200回を越せるようになった。

バドミントンの練習場所探し

お昼休みに公園へ行って20分ほど軽く練習した。そのときに連続回数が198回だった。あと2回足りなかったのが悔しかったのと、夜にがんばったらできそうかなという見通しをもっていた。

夜は近所で練習場所によさそうなビルを探してまわってみた。まずは少しおしゃれな区役所のビルの軒下へ行ってみた。

たまたま時間帯が悪かったのか、この場所が風の通り道になっているのか、練習を始めて5分ほどやって風の影響が強くて難しそうだったのですぐに撤収した。人通りが少なく照明もよい感じなのだけど、バドミントンの練習は風が強いとどうにもできない。

付近を散策しながら旧居留地にある別のビルへ。従業員の通用口がやや近いところが懸念。従業員が出てきたときにこいつ何しているの?と思うかもしれない。私の視点からもややパーソナルスペース/練習スペースを狭く感じるところはある。風の影響は受けにくい構造にはなっている。ここで15分ほど練習して267回継続できた。初めて200回を超えた。その後、あまり回数が続かなくなったのでまた散策して別のビルへ。

ここも広くて明るくて夜は施錠しているようにみえる。ここは従業員と会うこともない。よい場所なんだけど、照明が明る過ぎて見上げたときにシャトルと照明が重なってしまうと眩しい。照明が明る過ぎても練習しにくいことに気付いた。ここでも20分ほど練習したのに200回を超えなくて次へ移動する。照明が目に入るせいかもしれない。

最後はホームのビルへ。他のビルで練習してみてホームのビルのよさを実感した。もっとも練習スペースが広い。そして照明を背中側にして練習するスペースも十分にある。そうすると、見上げても照明とシャトルが重なることはないので眩しくて失敗してしまう状況を避けられる。構造的に風の影響も受けにくい。ここで20分ほど練習していたら398回、266回、349回と200回超えを3回できた。

フォア持ちとバック持ちのリフティングをしていて安定的するようになってきた。うまくラケットのスィートスポットで打てば真上にシャトルが上がる。50回ぐらいならほとんど動くこともなく上げられる。だいたい100回に1-2回ぐらい、失敗してシャトルをラケットのフレームに当てたりしてシャトル操作が乱れる。ドタバタしてリカバリする。これまではそのときに焦ってしまってシャトルを落とすことが多かった。なぜ200回以上続くかというと、その稀に失敗したときのシャトル操作をリカバリできるようになってきたから。つまり5回ぐらいミスしたときにリカバリできれば200回は続くということになる。これはメイビスフィールドのシャトルを使ったときの話し。

次にエアシャトルを使って同様にリフティングをしてみると最高で50数回ぐらいしか続かない。これはラケットのフレームまたはフレーム近くのガットで弾いてしまうと、コルク部分がプラスチックなために反発せずに落としてしまったり、あらぬ方向へ飛んでいったりしてリカバリがとても難しい。つまり、ラケットコントロールをうまくやらないとエアシャトルでリフティングを継続するのはメイビスフィールドよりもずっと難しい。次の目標としてはエアシャトルで200回を越せるようにラケットコントロールの練習をするのがよいように思える。

テストとビルドタグ

go ではテスト用途のパッケージを httptestiotest といった、通常アプリケーションとしてパッケージを提供しているものもある。しかし、通常のパッケージにしてしまうと、アプリケーションをビルドしたときにテストコードもバイナリにも含まれてしまう。依存パッケージの管理やバイナリサイズを減らす上で不要なコードはビルド対象外になる方が望ましい。自分たちが書いたソースコードがアプリケーションに含まれることはサイズの視点では問題ないが、テスト向けの依存パッケージもアプリケーションに含まれると意図せずバイナリサイズが大きくなってしまったり、パッケージの依存解決に時間がかかったりしてしまう懸念がある。そのため、ビルドタグを用いてテスト用途のパッケージはテストのときしかビルドしないように制御する。

例えば integration というビルドタグを設ける。テスト用途の util パッケージを定義するときは次のようにソースコードを記述する。

//go:build integration

package util

ビルドタグを指定せずに結合テストを実行しようとすると次のようなエラーが発生する。

$ go test ./tests/...
# example.com/tsets/mypackage
package example.com/tsets/mypackage_test
	imports example.com/tests/util: build constraints exclude all Go files in path/to/tests/util
FAIL	example.com/tests/mypackage [setup failed]

結合テストを実行するには次のように明示的にビルドタグを指定して、テスト用途のパッケージをビルドしてテストが実行されるようにしないといけない。

$ go test -tags=integration ./tests/mypackage/...