資料作りを丸半日

23時に寝て何度か起きて7時に起きた。起きたものの、なんかしんどくてお昼前まで寝てた。

課題管理勉強会の資料作り

出張前の定例作業になりつつある。本当は余裕をもって事前に資料作りしておけばよいのに、日々の余裕がないから出張直前の日曜日に資料作りしている。これはよくない兆し。次の課題管理勉強会は エンジニアリング組織論への招待 を取り上げる。Chapter 1 の思考のリファクタリングから、私が関心のあるところ、もしくは課題管理で解決できそうな話題などを重点的に取り上げる。たたき台はできた。構成や進行をさらに練りたいので少し寝かせてからもうちょっと考える。読み返していると忘れていたことを思い出したり、課題管理と密接な内容を再発見したり、本の内容をずっと覚えているとかないから自分の勉強にもなる。本当は参加者同士で内容の議論ができるといいんじゃないかと思うけど、少人数の勉強会ではないから発言しにくい空気がある。もしくは発言するのは一部のメンバーに限られてしまう。とくにリモート参加が多いと勉強会は盛り上がらない。それは オンライン飲み会が盛り上がらない理由 と同じ。

12時頃にオフィス来て、途中に休憩を取っているけど、ひと段落して気付いたら23時まわってた。明日は始発で新幹線に乗る。このまま起きたまま夜通し出張の準備をして新幹線で寝る作戦に移行する。

go の学び直し 静的解析編

23時に寝て2時に起きて5時ぐらいにも起きて7時に起きた。昨日は podcast 収録でたくさん話して疲れてしまってそのまま帰ってすぐ寝た。すぐ起きるんだけど。

ストレッチ

今日の開脚幅は開始前157cmで、ストレッチ後159cmだった。朝出かける前に開脚のストレッチしたら数値よくなるかな?と思ってやってみたらいつもより少しよくなった。ストレッチはいつも通りとも言えるし、腰の張りがまだまだ残っていることも確認できた。疲労が溜まっているんよな。毎週ストレッチしているからこの程度の疲労で済んでいるとも思える。お正月に実家から戻ってきてから1月の東京出張と35日は終えた。来週はまた2月の東京出張とその週末に49日がある。ここまで体力がもてばその次の法要は初盆なので少し空く。体力的に第4四半期の山場と言えるかもしれない。ただがんばる。

go の学び直し

Gopher塾 #3 - 静的解析を使ったGoの開発ツール制作 入門編 - DAY 1 に参加した。

過去にも Python とマクロ、インポートフックと抽象構文木Java のアノテーションプロセッサを試す など、メタプログラミングのアプローチやコード生成などを実務で使ってきたので静的解析にも関心がある。講義内容の詳細は書かないけど、静的解析のような難しい話題に対して4時間という短い時間でとてもよい講義になっていたと思う。go の静的解析の要点や提供されているツールなどを一通り学ぶことができた。もちろん、実用するには試行錯誤や習熟を必要とするけど、取っ掛かりとして十分な内容に思えた。

skeleton というツールを使って静的解析のための analyzer プロジェクトのひな形を作る。

$ go install github.com/gostaticanalysis/skeleton/v2@latest
$ skeleton myanalyzer
$ tree myanalyzer
myanalyzer
├── cmd
│   └── myanalyzer
│       └── main.go
├── go.mod
├── myanalyzer.go
├── myanalyzer_test.go
└── testdata
    └── src
        └── a
            ├── a.go
            └── go.mod

意図的にテストが落ちるようになっていてすぐ動作確認できる。

$ go mod tidy
$ go test                                          
--- FAIL: TestAnalyzer (0.05s)
    analysistest.go:448: a/a.go:5:6: diagnostic "identifier is gopher" does not match pattern "pattern"
    analysistest.go:512: a/a.go:5: no diagnostic was reported matching "pattern"
FAIL
exit status 1
FAIL	myanalyzer	0.349s

いろいろ説明を端折るけど、試しに FuncDecl の ast ノードに対して関数の行数をカウントする処理を実装してみた。analysis パッケージの Pass を使うと便利なユーティリティが提供されていて、静的解析をするときに面倒な処理をショートカットできて簡単に実装できることが理解できた。ここで作った analyzer は go vet で実行できるそうなのでプロジェクトの独自ルールを analyzer で実装して ci でチェックするといった運用もできる。応用範囲は広そう。

case *ast.FuncDecl:
	fmt.Println(n.Name, n.Pos(), n.End())
	start := pass.Fset.Position(n.Pos()).Line
	end := pass.Fset.Position(n.End()).Line
	fmt.Println("the number of lines:", end-start)

雑談の多い日

0時に寝て4時に起きて6時に起きた。本当はもっと早く起きて勉強会の資料作りやろうと思っていたけど、疲れと寒さでうまく起きれない。高速バスよりはずっと楽だけど、それでも土日に実家帰ってくると疲れが溜まる。次の週の週末になると蓄積度が違う。

隔週の雑談

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

年末にはらさん主催の忘年会に参加した。参加者は10人前後いたと思う。そのときにはらさんが「会社でオンライン飲み会やっても盛り上がらない?」といった話題があった。その意見には私も同意でおそらく参加者が5人以上いるとオンライン飲み会は盛り上がらない。オンライン飲み会の難しさは1つの部屋だとせいぜい3-4人ぐらいでないと話せない。1つの部屋に10人とかいると、実質話しているのは3人ぐらいで残りのメンバーは聞いているだけになる。それが盛り上がらない要因だと思う。オフラインの飲み会なら、例えば4人テーブルに3グループに分かれて、それぞれのグループが3つの会話が成立するから盛り上がる。そして、隣の会話が薄く聞こえたり、ちょっと休むときに隣のグループの会話に混じったりもできる。これと同じことをオンラインでもチャンネルを分けてやればよいというのは理屈の上で正しい。しかし、オンラインで能動的に別のチャンネルに入り直すのは複数の意味で障壁が高い。まずツールの操作が分かりにくいし、幹事が仕切るわけでもないので運用ルールも曖昧。仮に幹事がいても仕切れるのは1つのチャンネルだけで、他のチャンネルが意図した運用をしているかどうか、チャンネルを出たり入ったりしないと監視するのが難しい。オフラインの飲み会に近い状態にするのは、オンラインミーティングツール側で自動的にうまいこと配慮しないといけないのではないかといった話を、はらさんとしていた。

はんなりPodcast

はんなりプログラミング のコミュニティが はんなりPodcast(仮) を始めたらしい。私もちょくちょくはんなりさんのイベントに参加するので運営の方々とも懇意にさせていただいている。たまたまゲストで呼んでいただいた。感謝。内容はまた公開されてから書くので今日は収録の雰囲気だけ書いておく。かいせんさんとおがわさんとは、オンライン上でもよくやり取りしているので気軽に話すことができた。逆に私が調子に乗り過ぎて内容とは逸脱したことや自分の話したいことをわーっと話し過ぎてしまったのではないかという反省もあとになって思う。いま1人で働いているからこうやって自分の話しを聞いてくれる機会というのは貴重でそれはそれで楽しかった。ついつい自分の話しばかりし過ぎないように注意しないといけない。

オフィスアワー的なハドル

2時に寝て7時に起きた。お仕事は時間かけた割に成果でなくて、遅くに帰ってきて晩ご飯食べてダンまちみたら寝るのも遅くなった。

ハドルと雑談

今日から午前中はハドルミーティングに滞在するようにして、メンバーが気軽に雑談しやすい雰囲気を作ってみる。大学で言うところのオフィスアワー。初日だったせいか、どんなものかとお試しでチーム外の開発者が来てくれたりもした。メンバーの1人もお昼前にとくに用ないけど試しに来てみましたと軽く雑談した。ハドル中じゃなかったけど、別のメンバーも午後にコードレビューの詳細について聞きたいといったメッセージが届いてハドルをした。リモートワークしていても気軽に話しかけていいんやでと表明することで、いくらか話しかけるのをためらう心理的障壁が下がったことは確認できた。普通に誰でも考えて起きること。あとはこれを一定期間、1ヶ月とか2ヶ月とか続けてみてどのぐらいの雑談ができるかを記録して、効果がありそうなら次のアクションを考える。とくに用事もないけど、暇だから気分転換に雑談に来ましたというのが高頻度で起これば心理的安全性にとってもよいことじゃないかな。私が逆の立場なら、用事もないのに会社の人に話しかけるのは仲のよい同僚しかいなかったと思う。他のメンバーも気軽にハドルに滞在するようになれば、物理的にオフィスに出社しなくても雑談しやすい雰囲気は作れるかもしれない。

テックブログ公開

0時に寝て何度か起きて6時半に起きた。起きてから8時までだらだらしてた。寒くて起きれない。2月入ってしまった。早いなぁ。

テックブログのレビュー/公開

先週に草稿は書き上げていた ものの、レビューが滞っていた。他社のテックブログを勝手に書いて公開するわけにはいかないので慎重にレビューをお願いしていた。私がそういう特性の人間なのか、課題管理システムを長年使い続けてきたからそうなったのか、その両方なのか。私は Unit Bias が大きい方の人間だと思う。自分の中で完了したタスクをクローズせずに放置しておくのが精神的に耐えられない。すぐに対応しない残作業があるなら新しい issue に作った上で古い issue をクローズすることもたまにある。放置するのは嫌なので今日は関係者にどんどん確認してレビューを進めた。

公開して知人にシェアしてみたものの、あまり反応がよくないので大して関心を唆る読みものにはなっていないようだ。扱っている内容が悪いわけではなく、私の構成や文章力が拙いのだと思う。悔しいのでもう1回ぐらい、この記事に関連するテックブログを書いて関心をもってもらうような読みものにしたい。関西人だからかぶせてかぶせて天丼にしていく。

合間の遊撃

0時に寝て4時に起きて7時に起きた。晩ご飯に餃子の中身とニラと卵を炒めたものを食べてわりとよく眠れた。

遊撃の開発

ちょっと前に自分が 遊撃としての役割 を担っているのではないかと書いた。ある機能開発で javascript を用いてカスタムスクリプト を実行できるようにしたい。スポット的に私の手が空いていて手伝ってと言われたので実装している。開発していると集中しているから時間が経つのが早い。あとコードレビューのときよりもしっかりコードを読み込んだり、振る舞いをシミュレーションしたりするから、コードレビューのときに気付かなかったことや見逃したことにもい気付く。そして、それもついでにリファクタリングしていく。チームのメンバーに、過去に書いたコードをどんどん書き直すのはよいことだというのを、遊撃しながら教えていければいいなとも思う。課題管理システムの issue に調べたことや設計の素案のようなコメントをしていると、メンバーもコメントしてくれたりして、考え方や検証したことをどんどんテキストにして書いていく、言語化していくことの良さも、遊撃の中から学んでくれたりすると嬉しい。開発しながら、メンバーの教育や指導をどう進めるのがいいかな?とかも考えながら働いているのがマネージャーにやっているなという自己満足にもなっていたりする。だいぶマネージャーとしても自分自身にも慣れてきたんじゃないかと思う。

思い立ったらドキュメントを公開

23時に寝て2時頃に少し吐いて起きた。夜遅めに日本酒飲んでいい気分で寝たものの、もう夜に食べたらダメな体になりつつある。4時ぐらいまで起きててそれから寝て7時に起きた。

echo の静的ファイルの扱い

web api のドキュメントは openapi スキーマを使って生成 している。本当はこのドキュメントを gitlab pages で公開させたいのだけど、まだそのインフラ構築ができていなくて先送りになっている。いつもローカルで gitlab ci/cd がビルドしたドキュメントをみていたのだけど、ある機能開発をするときにローカルで web api ドキュメントみるの飽きたなと思って、web api サーバーに同梱してしまえと思い立った。テスト環境の web api サーバーは常に動いているのだから、そこに web api のドキュメントが同梱されていて、なんの不都合があろうか? (いや、なにもない) 。

次のドキュメントに echo で静的ファイルを扱う方法が書いてある。

ミドルウェアで実装されているようで簡単に静的ファイルを返せる。指定したパスのディレクトリ配下を扱えるのが Static で、指定したパスのファイルを扱うのが File になる。web api ドキュメントのようなものならキャッシュしてもいいなとは思ったものの、次の issue によると v4 ではミドルウェアで自前実装しないといけないらしい。v5 ではその仕組みが echo の機能として入るかもしれない。

その後、gitlab ci/cd で web api サーバーのビルド後、openapi.yml からドキュメント生成をして、任意の static ディレクトリに配置するように設定した。docker のマルチステージビルドを使うと簡単にできる。バックエンドやっていて、サーバーとインフラの両方に手を入れて機能を作っていくときの、うまくできると利便性と達成感の両方を得られるのが楽しい。web api サーバーがドキュメントを提供することは、要件に含まれるわけでも、誰かに指示されたわけでもない。私が勝手にローカルでドキュメントみるの飽きたと思って、勝手に作って、勝手に動くようにしただけ。こういう開発の遊びのゆとりや権限をチームのメンバーにも与えられるようにしていきたい。開発が楽しくて悪いことはなにもないと思うんよね。

だんご転がし

昨日から実家に帰ってた。23時に寝て5時に起きた。親が3時ぐらいから起きているから4時ぐらいから布団の中で起きてた気がする。親がだんご転がしで登る山の場所を確認しておきたいというから7時から山登りしてきた。

35日 (だんご転がし)

住職が来る前にだんご転がしを済ませておく。親戚に9時半に近所のお寺に集まってもらってだんご (おにぎり) を持って山登りをする。私は今日2回目。

言うても低い山なので往復20分ぐらいの山登り。登ったところから1人3個、崖に向かって後ろ向きにおにぎりを谷へ放り投げる。三十五日目の山参り というタイトルで日本昔ばなしでも放送されていたらしい。ググれば youtube でみつかるけど、著作権的によいのかどうかわからなかったのでここでは紹介しない。

11時から住職に来てもらってお経をあげていただく。お経後の住職の法話でだんご転がしの風習について話しがあった。そこで日本昔ばなしでも取り上げられたというのを教えてもらった。日本では淡路島にしか残っていない風習だという。その理由を聞いてみたら住職は次の3つをあげていた。

  • 島であること
  • 島民の大半が 真言宗 であること
  • お米が取れる地域であること

仏教の宗派が異なれば葬式の風習も異なる。たまたま島なので外部の影響を受けなかったのではないかという。昔は兵庫の北部や徳島県でもだんご転がしの風習はあったものの、徐々に廃れていったのは他の宗派の影響があるのではないかと話されていた。だんご転がしと言いながら実際はおにぎりを転がすのもややこしい歴史的経緯になっている。昔はお米は貴重であったため、おにぎりの代わりに団子を放っていた時代があって、その後またおにぎりに戻ってきたのではないかと考えられる。現代ならおにぎり転がしというのが正しい。お餅を祀るという習慣も関西では普通だが、関東では行われないという。それもお米が取れる地域の影響があるのではないかと話されていた。歴史の勉強になっておもしろかった。

本髙砂屋の金つば

本髙砂屋 という老舗の和菓子屋さんがある。洋菓子も売っているようだけど。35日に来てくれた親戚に配るためにお土産に買って帰っていた。これまでもお店があるのは知っていたけど、購入する機会がなくて初めてお店に入って買ってみた。詰め合わせは自由に好きなものを組み合わせてくれるという。

現在の「角きんつば」は、神戸元町の紅花堂(現在の本高砂屋)の創業者である杉田太吉により明治時代に考案されたものである。

wikipedia: きんつば

wikipedia によると、当初は刀の「つば」のような丸い形状で、その色から銀つばと呼ばれていたという。大阪で発明されたものが江戸に伝わったときに銀よりも金の方が景気がよいという理由で名前が金つばになったらしい。またいまの四角い金つばは本高砂屋さんがオリジナルで始めたことらしい。なるほど。歴史つきの神戸のお土産として素晴らしい。甘さ控え目で上品な風味になっている。あんこの甘いのが好きな人とそうじゃない人で好みは分かれるかも?私は甘さ控え目の方が好みかな。普通においしいと思う。

週末はドライブで気分転換

22時に寝て2時前に吐き気で起きて少しだらだらして寝て7時に起きた。

ストレッチ

今日の開脚幅は開始前154cmで、ストレッチ後158cmだった。あまり数値は振るわなかったものの、この1ヶ月ぐらいではもっとも復調しつつある。まだ腰の張りがやや残っていて全快とまではいかないものの先週よりはよくなりつつある気はする。先週から左右への開脚以外に前後の開脚のときの股関節のストレッチを重視するよう、トレーナーさんからも指示はあったものの、今週は全然そんな余裕がなくてあまり取り組めなかった。それを余暇でうまくできなかった分の、数値の悪化かなとも受け取れた。

2-2. 傾聴・可視化・リフレーミング

エンジニアリング組織論への招待 のメンタリングの技術の章を読み直し。前回 からだいぶ間があいた。

メンターはメンティに対して「問題を解決してあげよう」ではなく「モヤモヤしていない問題に変換してあげよう」と考えることが重要。問題を次のように考え、

  • 感情的に固執していて解けないので「傾聴」をする
  • 客観視できずに解けないので「可視化」をする
  • そもそも解けない問題なので前提を変える「リフレーミング」をする

というのが、メンタリングで意識すべき流れになる。

共感と同感の違い

  • 共感という言葉の意味は「相手がそのような気持ちになった理由を理解する」こと
  • 同感は「自分が相手と同じ気持ちになる」こと

傾聴において示すべきことは、「共感」であって、「同感」ではありません。

認知フレームとリフレーミング

  • 人はありのままに物事を見られない
    • 人は認知する枠組みの範囲でしか処理できない
    • この枠組みのことを「認知のフレーム」と呼ぶ
      • この外側にあることは「心理的な盲点」と呼ばれる
  • 対話によって認知フレームを変えることを「リフレーミング」と呼ぶ
    • 「解けない問題」を「解ける問題」へと変えていく

確認された前提を「一旦、この前提がなかったらどうなりますか?」というように外して考えるようにすることで、リフレーミングを促すことができます。 また、この中で「一番重要だと思うものは何ですか?」というように前提の優先順位を問うこともリフレーミングを促します。気になって仕方なかったことが、実はあまり重要ではないかもしれないと気がつく契機になります。

「情報の非対称性」を解消するには、

  • 自分の情報を相手に伝える
  • 相手の情報を自分が聞く

という行動をとればよいのですが、この当たり前のことができなくなってしまうケースがある

これは、メンター役になる人に対しても重要な警句です。メンターは、メンティの問題を「自分の課題」として捉えてはいけません。メンターにとっての課題は「メンティを自立的な問題解決」に導くことであって、「メンティの課題を解決すること」ではないのです。

この節を読み終えて、課題管理とは、メンターを必要とせず、自分で自分をメンタリングするツールとも言い換えられるかもしれないと思えた。課題管理を習熟すると自分で自分の間違いに気付けるというメリットを周りに伝えたりしていたことがメンタリングで大事なことのいくつかの共通することが書いてあった。

車を運転して実家へ

明日は父の35日なので夕方から購入した車で初めて実家に帰った。神戸の高速道路の路面が少し濡れていたり北淡で小雪が降ってきたりして、さっそくタイヤ周りを汚れてしまった。まぁ仕方ないか。door-to-door で1時間15分ぐらいで実家に帰れる。高速バスで帰るとこんな段取りになる。

  • マンションからバス停へ移動する (10分)
  • バス停でバスが到着するのを待つ (待ち時間10分)
  • 高速バスで移動する (1時間20分)
  • バス停まで親に車で迎えに来てもらって実家へ移動する (15分)

待ち時間の調整が入ると2時間ほどはかかっていた。これが自分の都合で移動できるので調整時間がない分のストレスが溜まらない。帰ろうと思って1時間強で移動できる気楽さがある。

コードリーディングの成果

22時に寝て4時に起きて1時間ほどだらだらしていて8時に起きた。生活のリズムが少しズレてきてしまっている。

最後のコードリーディング

先週からコードリーディングの勉強会をやっていて今日が最後。今日の対象のプログラムは windows サーバーで動く c++ のコードなので私はどちらも素人であまりよく分からない。上長の判断で別チームのベテランの開発者に来てもらうとよいとアドバイスを受けてお願いして来てもらった。これは本当によかった。実装されたコードだけではなく、設計を見直した方がよい視点なども指摘してもらって、もう少し時間をかけてこの windows プログラムを改修した方がよいと私は判断した。windows サーバーをクラッシュさせてしまうリスクのあるサービスにフックして実行されるコードを書いているので、windows サーバーの振る舞いや異常系処理の経験がないと潜在的にリスクのあるコードを動かしてしまう。web のアプリケーションなら多少のバグは後で直せばよいけど、os をクラッシュさせてしまうものは慎重にレビューした方がよいように思えた。次回の定例で話題にあげて課題を掘り下げようと思う。結論としてはコードリーディングしてよかったという話し。

pure go の javascript 処理系を使ってみた

23時に寝て2時に起きてだらだらして寝て7時に起きた。テンカイチ 日本最強武芸者決定戦 という漫画を読んでた。

pure go の javascript 処理系

ユーザー定義スクリプトを実行する要件がある。システム管理者がスクリプトを書くなら javascript がいいかなと次のリファレンスを調べたりしていた。

これらを読んだ結果として dop251/goja がよいだろうと判断した。README だけ読めばすぐに実装できてめっちゃ簡単で感心した。こういうライブラリを私も会社のプロダクトとして作ってみたい。万人が使うものではなくても、必要なときがたまにあって、すごく使いやすいみたいな。こんな感じで goja の機能を使ってライブラリ実装してみた。

type FunctionCaller func(funcName string, args ...interface{}) (interface{}, error)

func NewFunctionCaller(script string) (FunctionCaller, error) {
	vm := goja.New()
	_, err := vm.RunString(script)
	if err != nil {
		return nil, err
	}
	return func(funcName string, args ...interface{}) (interface{}, error) {
		f, ok := goja.AssertFunction(vm.Get(funcName))
		if !ok {
			return nil, fmt.Errorf("failed to get function: %s", funcName)
		}

		funcArgs := make([]goja.Value, 0, len(args))
		for _, arg := range args {
			funcArgs = append(funcArgs, vm.ToValue(arg))
		}
		value, err := f(goja.Undefined(), funcArgs...)
		if err != nil {
			return nil, fmt.Errorf("failed to call javascript function: %w", err)
		}
		return value.Export(), nil
	}, nil
}

Is it goroutine-safe? によると、goroutine-safe ではないので毎回 js の runtime を生成する必要がある。用途によっては、実行したいスクリプトが大きくなるとオーバーヘッドを無視できない状況もあるかもしれない。うちの要件は小さいユーザー定義スクリプトを実行するだけなのでおそらくそれほど問題にはならないだろうという想定。