私が歌川です

@utgwkk が書いている

「SCRUM BOOT CAMP THE BOOK スクラムチームではじめるアジャイル開発」を読んだ

普段からスクラムチームの一員として開発をやっているのだけど、自分にスクラムの語彙や前提知識が足りていないんじゃないか、何が基礎概念でどこがアレンジされている部分なのか、などいろいろ思っていたので買って読んだ。

要点を新人スクラムマスターの「ボクくん」が各所でまとめてくれているし、文章も難しくないのですらすら読み進めることができた。入門書としてはよさそうな雰囲気がする。もっと言うと基礎編だけ読むぐらいでも早いうちにやるとよかったですね。

「適応」の話はけっこう身に覚えがあるかもしれない。決まっているものが不可解でも決まっているからと従うのではなく、それを変えていけないか、という議論はよくあるだろう。もうちょっと具体的な実装の話に踏み込むと、linterのルールを無効にするかどうか決めるのも「適応」なんじゃないか。

ようは先の見通しを立てやすくするのと、対話・問題発見に重きを置いている、という話だと理解している。ベロシティがどんどん上がっていけばよいのではなく、安定しているほうがよいのは、見通しを立てられるし、ベロシティが安定しないことを通じてチームの問題の予兆に気づけるから、ということなのか。

ここでようやく前提知識が見えてきたという段階なので、アレンジされている部分についてはチーム側と話していくことになるだろう。この文章は業務連絡を兼ねています。

reflectパッケージでstructのunexportedなフィールドにアクセスするイディオムの正当性を (一部) 確かめる

生きてるといろいろなことがあり、リフレクションでstructのunexportedなフィールドに値を書き込みたくて調べていたら、以下のStackoverflowの回答が見つかった。

stackoverflow.com

以下のようなイディオムでstructのunexportedなフィールドにアクセスできる*1

type S struct {
    a int
    b int
}

s := S{}
rv := reflect.ValueOf(&s).Elem()
for i := 0; i < rv.NumField(); i++ {
    field := rv.Field(i)
    field = reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())).Elem()
    field.SetInt(1000)
}
fmt.Printf("%#v\n", s)

このイディオムでunexportedなフィールドの値を読み書きできるようになる原理は goでreflectを使ってunexported fieldの値を見る - podhmo's diary で解説されているけど、ここで unsafe.Pointer を使ってよい理由がパッと分からなかった。

元のStackoverflowの回答には以下のように書いてあるので、根拠を確かめることにする。

This use of unsafe.Pointer is valid according to the documentation and running go vet returns no errors.

unsafe.Pointer のドキュメントには、以下のパターンで unsafe.Pointer を使うのはvalidである、と書いてある。

  1. Conversion of a *T1 to Pointer to *T2.
  2. Conversion of a Pointer to a uintptr (but not back to Pointer).
  3. Conversion of a Pointer to a uintptr and back, with arithmetic.
  4. Conversion of a Pointer to a uintptr when calling syscall.Syscall.
  5. Conversion of the result of reflect.Value.Pointer or reflect.Value.UnsafeAddr from uintptr to Pointer.
  6. Conversion of a reflect.SliceHeader or reflect.StringHeader Data field to or from Pointer.

このうちreflectパッケージが関係するのは 5. だけなので、5. の条件を満たすことを確認する。

unsafe.Pointer を使っている部分だけに着目すると、以下のような式になっていることが分かる。

unsafe.Pointer(field.UnsafeAddr())

この式では、 reflect.Value 型の UnsafeAddr() メソッドを呼んで得られた uintptrunsafe.Pointer に変換している。なので、確かに 5. の条件を満たす。

以降のreflectパッケージを使った処理の動作原理については、先述したブログ記事で解説されているので、そちらを参照してほしい。しかしunsafeっていう言葉が出てくると身が引き締まりますね。

*1:完全なコードは https://go.dev/play/p/Fn48VJfNO9a にある

この言葉は誰かを傷つけるだろう、と書いては消したり、口をつぐんだりしている。そうやって行き場を失った言葉たちが積み重なっていくと、心が磨り減っていき、ある日静かに自分を殺すことになるのだろう。

濁流のように流れ出るものに対する恐怖、自分が自分でなくなるような恐怖と言えばいいのか、そういうものに怯えながら少しずつ文を継ぎ足している。自分が自分でなくなる、というよりは、暴力性を抑えているというべきなのか? 果たしてそれは暴力なのか、あるいは別の何かなのか。

Duolingo日記

Duolingoでポチポチやっているだけだと文法や単語の変化規則とかは分からなくて勘でやるしかない、という課題感から、東外大言語モジュールを読むようになった。

www.coelang.tufs.ac.jp

Duolingoだけでは分からないことも教えてくれる。なんで数詞が2種類あるのか、そういえば日本語もそんな雰囲気あるな、とかそういうことを思い出させてくれる。

あと発音の違いがぜんぜんわからん。

連日、激しく飲酒しているため、パフォーマンスに支障が出ていると言わざるを得ない。週半ばでこういう調子だとややきついので来週からはセーブしておきたいところ。

オイスターソースでチャーハンを作るのにハマっているけど、さすがに具がないと味気ないのでなんか探したい。味気ないというか味や食感に変化がない。日持ちしてだいたい美味しいと嬉しいけど、そんな具あるんですか。

パスポート取った

手続きが面倒そうとか、戸籍謄本を取り寄せるハードルが高いとか、いろいろあったけど徐々に解決されていった結果ついにパスポートが登場した。

モチベーション

韓国方面のブルーアーカイブの二次創作を摂取したい、というのが大きい。このためにDuolingoの韓国語コースもやってる。

ここで韓国語の単語を1つご紹介すると、「고양이」で「猫」という意味になります。コヤンニーって言ったらネコチャンです。これさえ知っていれば暮らしが豊かになる。わかりましたか?