NaaN日記

やったこと、覚えたことを発信する場

憧れのRubyKaigiに行ってみた

CNaanです。

RubyKaigi 2025に行ってきました。

Rubyとの出会いは、2018年に島根県で行われたRuby合宿がきっかけでした。
大学1年の当時お世話になっていた先生がRubyを推していて、合宿に行っておいで、と言われ、Rubyを勉強し、島根県に旅立ちました。
今回のRubyKaigiでは、この時にもらったTシャツを着て行きました。

cnaan.hatenablog.com


思えばはてなに入社する前の面接でも、id:onk さんにRubyKaigiとか、行ってみたいんですよね〜とか言った記憶があります。
それから数年経って、次のRubyKaigiはCNaanの地元でやるぞということで、運命を感じて申し込みました。

普段からRubyを毎日書くタイプではない(電卓の代わりや適当な乱数を生成したい時にirbを使う程度)のですが、とても楽しく参加できました。

スポンサーブース

スポンサーブースは色々まわりました。特に覚えているものをいくつか。

TOKIUMさんのブースでは、抽選会で技術書を引き当てました!
Matzさんのエッセイ本を選んだ後、Matzさんにサインを頂きました🙌
2018年のRuby合宿のときは、サインをもらおうか悩んで貰いに行かなかったことがあったので、7年ぶりの達成ですね。

ほかにもmovさんのゲームを遊んだり(最後0秒で抜かれて圏外になってしまった!)しました。

場内色々なスポンサーブースでクイズが出されていたんですが、個人的にはTimeeさんのクイズが一番好きでした。特に初日のクイズが良かったです。三日目は確認するのを怠ってしまった……。

並べ方の都合で写真には全部入っていないのですが、色々持って帰りました。

TimeeやQiitaのストレスボールは、いいですね。とてもかわいい。
primeNumberさんでは素数スピード対決をしてスマホスタンドやバッグハンガーになるキーホルダーをもらいました。便利!
cookpadさんにもらったフードクリップも今はポテチを挟んでくれています。
OPTiMさんのブースではカラビナマルチUSBケーブルを貰いました。
前に使っていたケーブルを最近紛失してしまったので、とても嬉しいです。


スタンプラリーという仕組みも面白いですね。全部回って押してもらいました!
会場マップがなかったので、途中迷子になると難しかったですね。DrinkUp!イベントでSTORESの社員の方に少し手伝ってもらいました。



DrinkUp!

DrinkUp!があるようなイベントには初めてでした。
公式のオフィシャルパーティ以外には、二つ参加しました。

  • TokyoDevさんの「Women and Non-binary Dinner & DrinkUp!」(0日目)
  • STORESさんの「STORES CAFE at RubyKaigi 2025」(2日目)

Rubyを日頃から書いているわけではないこともあって、DrinkUp!はRubyKaigi初参加者向け枠があるところなどを中心に選びました。

TokyoDevさんのイベントは、女性・ノンバイナリーが集まるイベントということで、選びました。
色々な人と会話できたこと、PikminBloomのフレンドが増えたことも嬉しかったです。

STORESさんのイベントは、ノンアルコールで子連れOKだったので選びました。
CNaan自体は一人で参加したものの、同じテーブルの方を中心に、こちらも色々な方とお話できました。
特にクワトロフォルマッジっぽいピザがとてもおいしかったです。個人的にまた行きたいです。

どちらのイベントもとても楽しく、参加してよかったです。

おわり

最後に、ひめぎんホールの舞台には何度か行ったことがあるので、懐かしかったですね。
また愛媛で面白いイベントがあると良いなと思いました。


ありがとうございました!

GORMのUpdatesに構造体を渡したらupdated_atが自動で埋まらなかったので実装を見に行ってみた

この記事は「はてなエンジニア Advent Calendar 2024」の34日目向けに書きました。

developer.hatenastaff.com

昨日は、id:koudenpa さんのCloudWatchメトリクスの歩き方 - koudenpaのブログでした。
メトリクスは時々見てますが、よく迷子になりながら探しているので、参考にできそうです。
エルデンリングがどこまで進んだのかも、楽しみですね。


こんにちは。id:CNaan です。普段はPerlを書いていて、ORMapperはTeng - very simple DBI wrapper/ORMapper - metacpan.orgを使っています。

Perlの開発では、レコードの更新のためupdateメソッドを呼び出すとき、「updated_atが指定されていなかったら、updated_atに現在時刻を自動で入力する」という処理を入れています。
そのため、普段の開発では、updated_atを意識していません。
MySQLでの ON UPDATE CURRENT_TIMESTAMP 句は使っていません。

// userテーブルは、id, name, created_at, updated_atを持ちます。
$teng->update('user',
    {
        name => 'new_name',
        // updated_atは指定していない
    },
    {
        id => 1
    }
);

そこで、同じ処理をGORMでやろうと思って、次のようなUPDATEを書きました。

type UpdatingName struct {
	Name string
}

func main() {
        // 〜〜 DBとの接続などは省略 〜〜

        // 更新するカラムを構造体に持たせることで制限しようとした
	updatingName := UpdatingName{
		Name: "new_name",
	}

	db.Table("users").Where("id = ?", 1).Updates(updatingName)
}

これで、ユーザー名が変更されたことを確認して開発を完了した後で、
ふと、「あれ、updated_at、古くね?」と気づきました。

テストでも、名前が変わっている、などは確認していましたが、updated_atが新しくなっている、は確認していませんでした。

GORMでupdated_atを更新するには

こうして、社内で、「updated_at、自動的に埋まるものだと思ってました〜」と話をしていたところ、
「GORMだとCreatedAt, UpdatedAtを自動で更新してくれるはずだけど……」という話になりました。
gorm.io


さて、ではどうすればUpdatedAtが自動で埋まるのでしょうか?

早速ですが、上記の記事には、

GORMの規約では、作成/更新時間をトラッキングするのに CreatedAt, UpdatedAt を使用します。それらのフィールドがモデルに定義されている場合、作成/更新時間に現在時刻を値としてセットします。

とあります。

type UpdatingName struct {
	Name string
	UpdatedAt time.Time
}

したがって、モデルにUpdatedAtを持たせると更新できそうです。
ただ、これだけだと exhaustruct のlinterの設定があった場合に引っかかってしまうので、

	updatingName := UpdatingName{
		Name: "new_name",
		UpdatedAt: time.Time{},
	}

UpdatedAtにゼロ値となるような構造体を渡す必要があります。
しかし、毎回UpdatedAtをモデルに持たせないといけないとなると、どこかで忘れそうですね。

実装を見に行ってみる

他の方法を探すため、実際のGORMのソースコードから、UpdatedAtに関係する処理を探してみます。

	if v, ok := field.TagSettings["AUTOUPDATETIME"]; (ok && utils.CheckTruth(v)) || (!ok && field.Name == "UpdatedAt" && (field.DataType == Time || field.DataType == Int || field.DataType == Uint)) {
		if field.DataType == Time {
			field.AutoUpdateTime = UnixTime
		} else if strings.ToUpper(v) == "NANO" {
			field.AutoUpdateTime = UnixNanosecond
		} else if strings.ToUpper(v) == "MILLI" {
			field.AutoUpdateTime = UnixMillisecond
		} else {
			field.AutoUpdateTime = UnixSecond
		}
	}

https://github.com/go-gorm/gorm/blob/f482f25c714b67562af1d487a669d80a527963b3/schema/field.go#L304-L314

これを見ると、以下のどちらかを満たしている場合、AutoUpdateTimeが埋まりそうです。

  • フィールドにAUTOUPDATETIMEのタグが設定されている
  • タグはないが、フィールドの名前がUpdatedAtであり、DataTypeがTimeまたはIntまたはUintである

フィールドの名前はUpdatedAtなので、この条件は満たしていそうです。

さらに実装を見ていきます。
構造体の場合、update.goで処理されるようですが……どうやら、渡された構造体の中にupdatedAtがあるかを見ているので、構造体の要素として持っていないと自動で更新してくれないようです。

    // stmt.Schema.DBNames, updatingSchemaどちらも渡された構造体のカラム名の要素しか持っていない。
    for _, dbName := range stmt.Schema.DBNames {
        if field := updatingSchema.LookUpField(dbName); field != nil {

https://github.com/go-gorm/gorm/blob/f482f25c714b67562af1d487a669d80a527963b3/callbacks/update.go#L260-L297

おっと、DBNamesが構造体のカラムしか持っていなかったのは、Tableを使っていたからのようでした。
Tableの代わりに、Modelを用意してみます。

    type User struct {
	ID          uint
	Name        string
	CreatedAt   time.Time
	UpdatedAt   time.Time
    }

    func main() {
        // 省略
        user := User{
		ID: 1,
		Name: "cnaan",
		CreatedAt: time.Now().Add(time.Hour * -2),
		UpdatedAt: time.Now().Add(time.Hour * -2),
	}
        db.Model(&user).Where("id = ?", 1).Updates(updatingName)
    }

Modelを使うようにすると、stmt.Schemaおよびstmt.Schema.DBNamesは、そのテーブルのモデルのカラムを全て持ちます。
ただ、updatingSchemaは渡されたnameのみの構造体なので、updated_atはif field := updatingSchema.LookUpField(dbName)の条件が false となり、やはりupdated_atの自動更新はできなさそうです。

map[string]interface{}を使う

構造体の場合に、updated_atを自動で埋めることは難しいとわかったので、他の方法も確認します。

レコードの更新 | GORM - The fantastic ORM library for Golang, aims to be developer friendly. によると、Updatesには、構造体だけでなく、 map[string]interface{}も渡すことができるようなので、その場合も見てみます。


map[string]interface{}の場合は、ここで処理されそうです。
https://github.com/go-gorm/gorm/blob/f482f25c714b67562af1d487a669d80a527963b3/callbacks/update.go#L192-L246


構造体の場合同様に、Table名を指定するパターンだと、updated_atは更新されませんでした。
stmt.Schemanilになるので、AutoUpdateTimeの処理の前に打ち切られてしまいます。

db.Table("users").Where("id = ?", 1).Updates(map[string]interface{}{"name": "new_name"})

ゼロ値を渡すとどうでしょうか?

db.Table("users").Where("id = ?", 1).Updates(map[string]interface{}{"name": "new_name", "updated_at":time.Time{}})
// Error 1292 (22007): Incorrect datetime value: '0000-00-00' for column 'updated_at' at row 1

エラーになりますね。

Modelを使うことにします。

db.Model(&user).Where("id = ?", 1).Updates(map[string]interface{}{"name": "new_name"})

stmt.Schema に値が埋まりました。カラムも全て揃っています。

&schema.Schema{
  Name:      "User",
  // 省略
  DBNames: []string{
    "id",
    "name",
    "created_at",
    "updated_at",
  },
}

AutoUpdateTimeも、1になっていますね。

&schema.Field{
    Name:      "UpdatedAt",
    DBName:    "updated_at",
    BindNames: []string{
      "UpdatedAt",
    },
    EmbeddedBindNames: []string{
      "UpdatedAt",
    },
    DataType:               "time",
    GORMDataType:           "time",
    PrimaryKey:             false,
    AutoIncrement:          false,
    AutoIncrementIncrement: 1,
    Creatable:              true,
    Updatable:              true,
    Readable:               true,
    AutoCreateTime:         0,
    AutoUpdateTime:         1,
    // 省略
}

どうやら、Modelを使うことで、Modelが持っているupdatedAtがhttps://github.com/go-gorm/gorm/blob/f482f25c714b67562af1d487a669d80a527963b3/schema/field.go#L304-L314のモデルのParse処理を通過するようですね。

あとは、map[string]interface{}の場合は、両方Modelが持っているSchema(stmt.Schema)を見ているようです。
structの場合は`updatingSchema`のLookUpFieldを見ていたので、そこが大きく処理の違いとなっていそうですね。

    for _, dbName := range stmt.Schema.DBNames {
        field := stmt.Schema.LookUpField(dbName)

https://github.com/go-gorm/gorm/blob/f482f25c714b67562af1d487a669d80a527963b3/callbacks/update.go#L227-L228

したがって、updated_atを意識せずにUpdatesを書きたい場合には、Modelを持たせてmap[string]interface{}を使うのが一番良さそうです。

db.Model(&user).Where("id = ?", 1).Updates(map[string]interface{}{"name": "new_name"})


結果の確認には、k0kubun/pp の結果を貼り付けました。
PerlのDDP(Data::Printer)と似た感じで出せるので、便利ですね。
github.com

また、初めて読むコードは、Copilotに聞いてみるのも便利ですね。
ヒントをもらえることがあります。

CopilotにUpdatedAtを自動で埋める実装をどこでやっているか尋ねる様子


では、自分は先月手に入れた逆転検事の続きをやって、事件を解決してきます。

はてなのカレンダーは、明日もまだ続く予定です。
はてなエンジニア Advent Calendar 2024 - Hatena Developer Blog

RedisのexpireにNXをつけた方が良かったとき

特定の時間にリセットするようなキャッシュをHashを使って管理したい、というときはNXをつけた方が良かったです。

次の使い方を想定する。

  • 1時間に一度、0分のタイミングでキャッシュをリセットする
  • HGETでfieldを探して、すでに存在していればvalueを使う
  • 存在しなければ計算してHSETでfield valueを追加し、次の0分までの秒数を有効期限としてexpireで設定する

12:00ちょうどのとき、残り3600秒間利用したいので、expireで3600を指定した。

redis> HSET myhash field1 value1
(integer) 1
redis> EXPIRE myhash 3600
(integer) 1

次に、12:30にfield2へのアクセスがあったので、計算し、追加した。

HSET myhash field2 value2
(integer) 1
EXPIRE myhash 1800
(integer) 1

このやり方だと、EXPIREに設定するときに計算した秒の値がズレていると毎時0分を超えてキャッシュしてしまう。
さきほどfield2を追加したとき、厳密には12:30:00.100だったので、13:00:00.100まで延長された。

このあと、13:00:00.000〜13:00:00.099の0分を超えたキャッシュが存在している間に同じように新しいfield valueをセットすると、0分のときに次の0分までの時間は3600秒なので、この1時間の間に作成したキャッシュをexpireせずに、1時間延長できてしまう

NXをつける

EXPIREにはOptionsとして、NXやLTが設定できるので、これを設定することで、キャッシュを確実に期限切れ状態にできる。

EXPIRE | Docs

  • NX: 有効期限の設定がない場合のみ、有効期限を設定できる
  • XX: 有効期限が設定済みの場合のみ、有効期限を設定できる
  • GT: 有効期限が設定済みで現在より大きい場合のみ、有効期限を設定できる
  • LT: 有効期限が設定済みで現在より短い場合のみ、有効期限を設定できる

今回の使い方だと、keyに対しての有効期限は固定なので、expireを設定するのは最初の一回だけで良い。

HSET myhash field3 value3
(integer) 1
EXPIRE myhash 600 NX
(integer) 0 -- 操作がスキップされた。

こうすることで、初回以降は有効期限が上書きされなくなるので、12:00:00.300に最初のキャッシュの有効期限を3600で作ったとしても、13:00.00.300にはEXPIREされる。
(13:00.00.200にキャッシュを更新しようとしても、操作がスキップされる)

このように、ひとつのkeyに要素を何度も追加するようなときには、毎回expire設定を上書きしない方が良い。


しかし、13:00:00.000ぴったりにEXPIREしたい、という場合には、この方法は使えない。
PEXPIREでミリ秒単位の有効期限を設定すればより0秒に近づくが、ミリ秒だとしてもズレる。
したがって、ミリ秒単位の遅れも許されずにぴったりにEXPIREしたい場合には、他の方法を検討する必要がある。

他の方法

  • EXPIREAT | Docsというのもあって、これだと有効期限を厳密なunix timestampで設定できるので、ぴったりのunix timestampを計算すれば、その時間ぴったりにキャッシュを切らすことができる
    • 今回の例のような、ある時間までを有効期限に決めたい場合、unix timestampを計算してセットするのが素直な実装だろう
  • 切り替えタイミングの時間をkeyに含めてしまう
    • 時間経過でkeyが変わるので、前の時間のキャッシュは取得できない
  • key単位ではなく、fieldごとに有効期限を決めたいなら、HEXPIRE | Docsもある

PHPカンファレンス香川2024に行ってきた(5/11)

普段の業務ではPerlを書いていて、PHPは大学の授業でちょっと書いたことがあるくらいのid:CNaanです。

近所でやるとのことだったので、遊びに行ってきました。

phpcon.kagawa.jp

↑↑目が動いてめっちゃ可愛いのでぜひPHPカンファレンス香川2024を見て!!↑↑

大学の後輩たちに「学生無料らしいよ〜誰か知り合いいたら嬉しいな〜」とURL貼っておいたら直前にもかかわらず二人ほどきてくれました。やった!!

面白かったのが、なんと会場ではうどんが好きなだけ食べ放題でした。
基本はトッピングなしのかけうどんですが、企業ブースに行くとハンコを押してもらえて、きつねやおにぎり、温泉卵と交換できました。

CNaanはきつねが大好きなので、きつねと交換しました。
噂によると、最後の方はぶっかけうどんを提供していたらしい。

うどん。きつねトッピングつき

基本的には気になるトークを聴きつつ、スポンサーブースをぶらぶらして過ごしていました。

サイボウズブースではキントーンステッカーをもらいました。
もともと松山の人間だし、大学時代にはオフィスに行ったことがあるし、1年前のOSC(Tokyo/Spring@浅草)でもサイボウズさんのブースみたし、
ブースを見かけるといつも覗きに行っています。
第23回 学生エンジニアLT大会!!! in 愛媛 - connpass

キントーンステッカー


サムライズムさんでは、オープンセミナー2018@香川 #osk2018 - connpassで一回お話聞いたことあるんですよ〜とか雑談しながら、製品見せていただきました。
GitHub Actionsと連携して、テストが落ちた箇所のコードにすぐジャンプできる機能が魅力的で面白かったです。
mackerelチームにどうぞ、とビラを貰ったりしていました。

CICloneの紹介


あとは、STYLYさんのブースではVision Proをつかった体験ができました。
洋服の展示とか見せていただいたんですが、質感がわかる感じがして良かったです。
VRはゲームとかやるのも好きなんですが、実用的な感じのを見るとワクワクしますね。
VisionProはやっぱりQuest3と比べると映像が超綺麗。

会社にVision Pro買った人が5人くらいいて触らせてもらったんです〜とか雑談しました。

はてなか〜好きな人多そう!」
developer.hatenastaff.com

STYLY TECK BOOK

ほかにも、ミトラさんでは自分が香川の大学に通っていたこともあって、世間話が弾みました。
昔は電子カルテとか医療系の仕事にも興味があったなーー。
オフィスが通っていた大学から近くて知っている場所でした。

あとは「うずらの間」というid:uzullaさんが滞在している部屋もあったりしました。
いろいろお話しできて楽しかったです。


トークもいくつか聞いたのですが、特に次のトークが面白かったですね。
fortee.jp
speakerdeck.com


プロダクトの品質に向き合うためのテストについては、以前から興味があったので、話が聞けて良かったです。
参考にして、分析をしっかりとやっていけるようにしたいと思います。

  • デザインなど、初期の段階でQA項目を用意する
  • エンジニアが、他の範囲に影響がないと言った場合に、見ないのではなく影響がないことを確かめる


そういえば、かまぼこケーキもありました。
PHPカンファレンスってこんなに食べ物いっぱいもらえるんですか??

こんな感じで、腹一杯の一日を過ごし、帰宅しました。

帰り際に玉藻公園ペチュニアを無料配布していたので持って帰りました。
自転車を漕いでいたらナメクジ付きだったことに気づいたけれど、家に帰ったらいなくなっていたので落としたのかもしれない。

植え替えたペチュニア

↑この写真撮ってから、ブログを投稿するまでに2週間くらい経ってしまったので、結構育ってしまった……。

育ったペチュニア


来年以降も行なっていくぞという勢いを感じたので、今後も楽しみだ!

はてなTシャツ着て行ったけど上着羽織ってたので気づいてもらえなくて、Perl書いてますって言ったら「はてなですか?」って気づいてもらえました。
PHPカンファレンスに行くPerl書いてる人は大体はてならしいです。

3年ぶりリアル開催のOSC(Tokyo/Spring@浅草)に行ってきた

id:CNaan です。
2023/4/1(土)に開催された【3年ぶりのリアル開催】4/1 オープンソースカンファレンス2023 Tokyo/Spring@浅草 - connpassに行ってきました。

オフライン時代には、OSC広島とか、香川、徳島に参加したことがあって、関東地方のOSCには初参加でした。
久々、ということもあって関東以外の出展もあって賑やかでした。

今までは大学のサークルでの出展側での参加だったので、出展じゃない立場としての参加もこれが初めてかも。

入手したものとか

来場者プレゼントでポーチ的なもの(画像左)をいただいたのですが小さなシールを入れたりするのにとっても便利でした。
cartoonみのあるopenSUSEのシールがとてもかわいい。
Mozillaの紙バッグやOSCのTシャツもかわいいですね。 id:tmiyahar さんありがとうございます!

入手したいくつかのノベルティ


他には、軽く立ち読みして内容が面白かったので、親方Projectさんの「技術同人誌を書こう!」を買いました。

「サークル参加方法、抽選に落ちたときどうするか、ネタだし、執筆環境、印刷部数、etc.」と20章色々な話題を書いていて、読み物として面白そうだったのが購入の決め手でした。
直近で執筆するような予定はないけれども、書くぞ!となったときには参考にしていきたいですね。

調べたところ、oyakata - BOOTH親方Project | 技術書典もあるようでした。

「技術同人誌を書こう!」の同じ本は今入手するなら技術同人誌を書こう! アウトプットのススメ | 親方Project |本 | 通販 | Amazonになるのかな?(BOOTHなどにある「ワンストップ!技術同人誌を書こう」との内容差分は知らないです)

親方Projectさんの「Podcastを始めよう」「技術同人誌を書こう!」

この本が好きそうな友人に、帰宅してから「これ買ったよ〜」とお伝えすると、2017年の冬コミで買った、と写真が送られてきました。

ワンストップ!技術同人誌を書こう

既に持っていてやっぱりこの本好きだったか、と納得しました。

出展まわるの良いね

本当は10時くらいに到着して回る予定だったのだけれど、早起きに失敗して12時すぎくらいに到着しました。
前日に会社のSlackで宣伝していた効果か、同じ会社の方(お忍びではなかった id:miki_bene さん)とも会えて、途中同じ建物の8Fでハンバーグを食べたりもしましたが、ちょうど全部回った頃に16時くらい、で4時間(実質3時間無いくらい?)じっくり楽しめました。

セミナーが無いと無計画でゆっくり回れるメリットがありますね。

基本的に端から回っていって、人があまり集まっていないところから見ていきました。
人が集まっているところは空いたタイミングを見て行きました。
今回久々だったからか元々そうだったか?、ほとんどのブースが眺めていると声かけ〜展示物の説明をしてくださる感じの雰囲気でした。

大学時代に原稿のやりとりでお世話になった、ユニバーサル・シェル・プログラミング研究所の方とも初めてお会いして会話できたのでよかったです。
振袖の方だよね……?と言われたのがちょっと面白かったです。そういえばそんなこともあったなと。
近影に良い写真がなくて、成人式関係で撮った写真を送りつけたのでした。

見た出展の感想をいくつか

特に印象に残っている出展をいくつか挙げると、

OSGeo日本支部さんは、ラズパイ(だったかな)に会場近辺の地図データを入れていて、関東のこのくらいの範囲なら、この中に地図データを入れることができるので、災害時でも公衆トイレ・交番・病院などのデータをオフラインで閲覧することができるのです、という展示をされていました。

自分の子供のためにプログラミング言語を作ってそれを自分の子供にやらせながら出展している方がいて、出展がうまい……!と思いました。
Scratchの次の言語としてCとかPythonをやらせるのはちょっと難しいので……というのでわかります〜!めっちゃ良いですね!!と会話したりしました。
今URLを調べていて、HPで坂井さんのブースだったことに気づいたので、かなり納得をしました(当日ふらふらとしていたので何も気づいていなかった……)。
坂井さんのところでSecHack365やりたい、と昔思っていたのですよね。

kozos.jp


プラレール計算機はすごかった!


サイボウズさんのブースでは、自作CPUと、自作CPUにテストを走らせるところを見せていただいたりとかしました。

「自作CPUに興味はありますか?」と聞かれて、可愛い女の子が表紙の本(伝説の名著をご紹介!『CPUの創りかた』|Tech Book Zone Manatee)を昔少し読んだのですが、最後まで読まずに積読になってしまっていて……と言ったのですが今思うと正直すぎたなと。

積読を一冊ずつ消化していかないとな……。


あとは、あのダークな学生だった id:masawadaくんが今では君のメンターになっているの……?という話をしたり、
masawadaくん結婚(1年前)おめでとうございます!と伝言を頼まれたりとか。

その他

終わった後、同僚と一緒にちょっとお寺の方へ歩いておみくじを引きました。
旗を持った人へついていく人たちや、写真を撮る人など、とても賑わっていました。

おみくじは初めてのYAPC - NaaN日記から引き続き大吉でした。
今年は良い一年になりそう?

その後、そういえば以前メンチカツを食べたいと id:yamakenji24 が言っていたのを思い出して(以前は閉まっていた)、買いに行きました。

浅草メンチ

衣に味がついているような、濃いめのメンチカツでした。

次回CNaanに会えるイベントは

未定です!7月末くらいのOSCには多分いるんじゃ無いかな〜?

初めてのYAPC

3/18〜京都に行って、YAPCとその前日祭を聴講しにいきました。
yapcjapan.org


前日祭では、LTが行われていて、特にPerl初心者が書いたコードのレビューについての発表が、共感できて好きでした。
空リストの判定の書き方とそのレビューが、あるあるだなーって思いました。

夜は、Helpfeel Techさんの懇親会に参加していました。
店について最初に頼んだ唐揚げが出てきたのが2時間後とかで、ここの注文はスタックなのか??とか会話していたのが楽しかったです。

当日は、前日に聴講するものを全て選んでから行きました。

前日祭で、低身長だと後ろの方に座るとスライドの下半分が見えない、ということに気づいたので、当日は前の方に座るようにしました。
そうしたら夜首が痛かったです。

どっちにいくか迷ったら知り合いではない方を見に行きました。
今回、あとから配信がありそうなのが大変嬉しいですね。

YAPCの全体的な感想

直接的なPerlの話が思ったより無かったのが意外でした。
もっとPerlのニッチな話を聞くイベントだと思っていたら、Perlを心に秘めた人たちの話でした。

個人的に、Perlの話をしている人の話が特に面白いな、と思ったけど(なぜなら最近Perlを一番書いてるから)、それ以外の話も実用的な話が多くて楽しかったです。
次は何か話題を持っていきたいですね〜。
参加しての満足度は120%くらいです。
他の企業の方とかと喋るのが本当に久々だったので、すごく楽しかったです。

ひとこと感想的なコーナー
  • 小さく始め、長く続けるOSS開発と貢献
    • コードの多様性の話が面白かった。CNaanさんのコードは〇〇だね〜〜っていつか褒められたい!
    • なんだかんだゆっくりでも仕事ができてしまうので、ゆっくり仕事してしまうけど、ショートカットが使えたら一回数秒の短縮になる、とかそういうちょっとの短縮もやっていくかあ、とモチベを上げられた(発表とはあまり関係ないかもな感想)
  • 入門 障害対応 「サービス運用はTry::Catchの繰り返しだよ、ワトソン君」
    • 外型監視のアラートで原因がわからないときは挟み撃ち法を使っている、L7→L3→L6……みたいな
    • 障害対応訓練と聞くと準備(エンジニア的な準備や訓練のための時間を貰う調整)にコストがかかりそう、というイメージだったけど、そんなに準備のかからない(準備に30分とか)訓練をやっている、とのことだった
  • 様々な環境へコマンドラインツールを提供する上での苦労とその対策
    • OS × Pythonのサポートがしんどいという話をされていて、大学の授業でみんながみんな色々なPythonの環境構築をしているのでサポートする側が大変だった、というのを思い出した(先生によってAnacondaだったりpipだったりした)
  • my new error...
    • アラートの監視の仕事だけをする、というのが大変そうだった。オオカミ少年問題を解決するために、ログレベルと使い分ける、といった参考になる話が聞けた
    • 個人的に例外投げるよりエラーオブジェクト返す方が好きなので、全体的に共感できる話だった
展示とか

カヤックさんでおみくじを引きました。

カヤックさんのおみくじ(大吉)

大吉やった〜🙌

絵馬にもお祈りをして、無事お祈りは後日叶いました。ありがとうございます!!


DeNaさんのブースでコップをいただきました。

YAPC KYOTO 2023コップ

そのほか、さくらインターネットさんや、マネーフォワードさんのブースで色々お話できて楽しかったです。

YAPCの話はここまでです。

つぎのひ

月曜日、出社のついでに会社の人に連れて行ってもらって、カレーを食べました。

Kamalのカレー

高校の同級生に会いました。桜が綺麗でした。

さいごに

次回CNaanに会えるイベントはコレです!!

ospn.connpass.com

浅草でお会いしましょう〜〜。

ゆるぼ: 4/2にお花見BBQがあるらしいんですが、一緒に誰か行きませんか〜。