じゃあ、おうちで学べる

本能を呼び覚ますこのコードに、君は抗えるか

ドメイン規約を lint で表現する — `Order` に `is_paid + payment_id` を共存させない

はじめに 長年、動いた DB を覗くと、たいていこういうレコードが眠っています。 { "order_id": 12345, "is_paid": true, "payment_id": null } is_paid = true なのに payment_id は null。 ドメイン上、 同時に成立してはいけない組み合わせ が静かに残り…

`rowan` で自家製 lint を書く — rust-analyzer の心臓部を流用する

はじめに エディタで .unwrap() を書いた瞬間、 clippy が黄色い波線を引きます。match で variant が漏れた瞬間、コンパイラが赤い波線を引きます。これは魔法ではなく、 rust-analyzer が rowan で構文木を作り、その上をルールが歩いている というしくみ…

31歳、もちろん俺らは抵抗するで?筋肉で

はじめに ※この筋肉はイメージであり現実の肉体とは乖離がある場合があります。 ある誕生日の朝、通知が、なかった。 母親からだけ、メッセージが来ていた気がする。 俺の人生はLINEの量で決まるかと嘯きながら、LINEの誕生日表示を非公開にした。20代の、ど…

コンパイル時に未設定フィールドを禁止する type-state builder

はじめに Builder パターンで「url を設定する前に build() を呼んでしまった」事故を、 コンパイルエラーで止める 書き方があります。type-state pattern と呼ばれています。PhantomData を使って builder の進捗状態を型に乗せる、 Rust 固有の idiom です…

自分のクレート外の型にメソッドを生やす — extension trait と sealed pattern

はじめに 「String に独自メソッドを追加したい」「外部クレートの型に1メソッドだけ生やしたい」場面があります。Rust の orphan rule のせいで、外部クレートの型に外部クレートのトレイトを直接実装するのは無理です。代わりに 自分のトレイトを定義して…

`lazy_static!` はもういらない — `LazyLock` と `OnceLock` の使い分け

はじめに Rust で「グローバル変数を遅延初期化したい」となったとき、長らく lazy_static! クレートが定番でした。今 (2026年) はもう不要です。標準ライブラリの LazyLock (1.80+) と OnceLock (1.70+) で全部書けます。マクロや外部依存も要りません。 た…

`Cow<'_, T>` で「変更が必要なときだけ allocate する」

はじめに 入力をそのまま返すか、一部書き換えてから返すか、関数の中で判定する場面があります。素直に書くと「変更しない場合も無駄に String::clone() してしまう」、または「&str を返したいが、変更があった時は所有データを返したい」というジレンマに…

newtype と `PhantomData` で「混ぜたら型エラー」を作る

はじめに UserId と OrderId を取り違えてバグを生み出す経験は、String で識別子を扱っていれば誰しもあります。Rust では newtype で別の型に分けるだけで、コンパイラに止めてもらえます。さらに PhantomData を組み合わせれば、「JPY と USD を足し算す…

おい、要件を動くものにしろ

はじめに ドキュメントは、書いた瞬間から腐っていく。 読まれない。検証されない。更新されない。それでも、要件と呼ばれ続けている。 第1部では、要件を言葉にする規律について書きました。引き出し、観察し、ジョブを見極めながら、業務領域の言葉で書く…

`NonZero<T>` で「ゼロではない」を型に乗せる

はじめに ゼロ割り、ゼロサイズ確保、ゼロインデックス。「ゼロでない数値」を期待する場面はあちこちにあります。これを runtime チェックではなく 型 で保証できる仕組みが NonZero<T> です。 Rust 2024 edition で書き味がさらに素直になりました。これまで</t>…

`thiserror` と `#[non_exhaustive]` で SemVer に強いエラー型を作る

はじめに Rust で「ライブラリのエラー型をどう設計するか」は永遠のテーマです。素朴な答えは2つあります。 アプリケーションなら anyhow で済ませる ライブラリなら thiserror で型付きエラーを返す これは2026年でも変わりません。この記事は「ライブラリ…

`if let` chain — Rust 1.88 / 2024 edition で実用フェーズに入った

はじめに Rust 1.88 (2025年) で if let chain が安定化されました。2024 edition のコードでは積極的に使えます。 && で if let 条件を連結できるようになり、ネストした if let を平らに書ける構文です。短い変更ですが、効果は大きく出ます。 何を解決す…

`let-else` で早期 return を素直に書く

はじめに Rust の let-else 構文は、Rust 1.65 (2022年) で安定化された機能です。古くからある機能ですが、2024 edition のクリーンなコードベースでは多用されます。clippy の manual_let_else ルールも 2024 では使うことが推奨されます。 「Option が No…

`unwrap()` を書きそうになったときの選択肢8つ

はじめに Rust で Option や Result から値を取り出すとき、つい .unwrap() を書いてしまう場面があります。動くし短い。だから書く。だけどそのコードは、エラー時にスタックトレースなしで panic します。本番で踏むと 「どこで何の理由で死んだのか」 が…

おい、要件を言葉にしろ

はじめに 察しの良いチームが、いちばん危ない。 書かなくても通じてきた、その通じ方が、AIには渡らない。書かれていない常識は、書かれていないというだけの理由で、消える。 要件定義は、長く「面倒だが避けて通れない上流工程」と呼ばれてきました。きち…

OWASP ZAP の finding を Rust/Axum の handler に戻して直す

はじめに vulnerable-app に ZAP の full scan を回すと、High finding が並びます。XSS、SQL Injection、Path Traversal。alert 名を眺めて、ふと気づく。これは「危険です」の一覧ではない。handler への差し戻し指示書だ。 OWASP ZAP を実行すると、HTML…

おい、夢は持たなくてもよいけど、失敗はしろ

はじめに 即答できなかった。 昨日、長崎大学の、学生たちからの問いに。 「AIに負けない人材になるには、何をやればいいですか」と。 何人もの学生が、言い方を変えて同じことを聞いてきた。真剣な目だった。生成AIが自分たちの未来を奪うかもしれない、と…

Argo CD ApplicationSet で PR preview の構成を Kind 上で検証した

はじめに 知りすぎていた。 ある PR のレビューで preview 環境が動かなくなった。原因を調べると、preview を立ち上げる shell script が別の PR の修正で壊れていた。preview を作る仕組みが、preview とは無関係な変更で壊れる。依存の逆転だった。 気に…

翻訳者がいるから、共通言語は整備されない - Architecture for Flow の読書感想文

翻訳者がいるから、共通言語は整備されない。 読み終えてから、この順序の逆転が頭から離れませんでした。そして、その「翻訳者」とは、戦略会議とコードレビューのあいだを10年走り回ってきた、ほかでもない私自身のことでした。胃のあたりは、いまも少し重…

おい、夢を持たなくても良いぞ

はじめに 夢がなくても、人は生きていける。人に語れるような大きな夢がなくても、「明日はもう少しうまくやりたい」と思う。その程度の小さな望みすら持てなくなることもある。でも、しばらくすると、また何かを望んでいる。語る夢がなくても、望むことはや…

Neovim 0.12 リリース内容まとめ

はじめに Neovim 0.12のリリースノートを開いて最初に思ったのは、「これ、lazy.nvim要らなくなるのでは」だった。ビルトインのプラグインマネージャ vim.pack。宣言的なLSP設定 vim.lsp.enable()。ビルトインの :Undotree。ちょうどNvChadからLazyVimに乗り…

LLM に足りないのは能力ではない。あなたの事情だ

はじめに エディタを開いたまま、手が止まっていた。 LLM(大規模言語モデル)が書いた Rust のコードを眺めている。WAL(Write-Ahead Log、データを安全に書き込むための仕組み)のセグメント管理。所有権(データの持ち主を明示する Rust 独自のルール)は…

Claude Code のスキルとして動作する日報自動生成ツールを作った

はじめに 夕方6時、日報を書こうとしてターミナルを開く。今日何をしたか——思い出せない。Slack を遡り、PR の履歴を見る。20分かけてようやく事実を集め終えたが、「今日の振り返り」の欄がまだ空白のまま残っている。 半年前に「Claude Codeのスラッシュコ…

SREはAgentic Engineering時代のHarnessになれるのか?

はじめに 深夜2時にアラートが鳴った。 ベッドから起き上がる前に、たぶん3秒くらい天井を見ていた。見ていたのか、目を開けたまま何も見ていなかったのか、正確にはわからない。通知音は聞き慣れたものだった。体が先に動く。ダッシュボードを開く。メトリ…

move || を200回書いて考えた、Rust とフロントエンドの距離

はじめに subnet.name.clone() と書いた。ボタンの on:click ハンドラにも move || を付けた。フィルタの状態を Resource に渡すクロージャにも move || を付けた。50行のコンポーネントに move が7回、.clone() が4回、.into_any() が3回。数えるつもりはな…

アーキテクチャモダナイゼーションの帯に「何度書き直しても、また遅くなる」と書いた理由 #devsumi #SRETT_Special #emconf_jp

はじめに 2026年2月19日、Developers Summitの会場に向かう電車の中で、スライドを開いた。40分の発表。500ページの本を翻訳して、そこから何を伝えるか。1ヶ月かけて構成を練った資料が、手元にある。正直、疲弊していた。5人で分担したとはいえ、各章のレ…

PostgreSQL の型を信じろ — CIDR/ENUM 型と SQLx の格闘記録

github.com www.postgresql.org はじめに SubnetMap は Leptos 0.8(Rust 製の Web フレームワーク)と Axum 0.8 で作った IP アドレス管理ツール(IPAM)だ。フロントエンドが動いた。画面にサブネット一覧が表示された。ボタンも押せる。フィルタも効く。…

Leptos 0.8 でフルスタック Rust を始める

leptos.dev github.com 本記事は Rust でフロントエンド開発をしたことがある、あるいはこれから試してみたいエンジニア を想定している。React や Next.js などの SPA/SSR フレームワークの経験があると読みやすい。 はじめに cargo leptos serve を叩いた…

おい、方法を捨てろ

はじめに テストが走っている。グリーンのバーがじりじり伸びていく。深夜1時。コーヒーはとっくに冷めている。キーボードに手を置いたまま、画面を眺めていた。 syu-m-5151.hatenablog.com syu-m-5151.hatenablog.com 「方法を学べ」で、方法を増やすことの…

AIのやりすぎで頭がおかしくなることにすら慣れた - 『AIのやりすぎで頭がおかしくなっている』を読んで

あの日のおかしくなりはじめた僕へ。良くなる見込みはない。 はじめに uiuさんの記事を読んだ。「AIのやりすぎで頭がおかしくなっている」。とても良い文章と内省だと思った。でも現在進行形ということは、まだ途中にいるということだ。まだ引き返せる場所に…