20250603

Hotwire ことはじめ

Turbo を使用してインラインのセル編集 CRUD の実装をしてみた。慣れれば面白い。turbo がイベントをインターセプトして fetch して専用ヘッダでリクエストして 対象の DOM の要素だけ書き換える感じらしい。

Ruby on Rails inline CRUD with Hotwire を見たのがきっかけ。従来のクラシカルな CRUD よりも UI 上で優れているのは間違いないと思う。これが Hotwire でできるようになったということか。

2025-06-03 08:20:28 +0900 +0900


20250529

obsidian の canvas と dataview をつかいはじめた

zettelkasten メソッドを obsidian にも実践しはじめてから、これまであまり探検してこなかった機能を試している。知のデータベースが整って情報がいろいろな次元から検索/照会/集約できるのはよい。

2025-05-29 08:42:46 +0900 +0900


20250525

「スプリント」モード

将棋ウォーズの「スプリント」モード(終盤の互角の局面から対局開始) が無料ユーザーにも開放されたからプレイしてみた。今までと全く違うプレイ体験だった。制限時間内で終盤力を磨くのに役に立ちそう。

2025-05-25 19:10:54 +0900 +0900


20250524

Zettelkasten Method with notion

chatGPT との会話で出てきた Zettelkasten Method について調べていた。ファイルの「内容」に関連付けるメタ情報ではなく「性質」に関連付けるメタ情報らしい。

この概念を利用すれば「内容」や「時系列」に加えて新しい次元(dimension) でファイルを検索することができて便利そうだ。同時にディレクトリに代表される階層構造に縛られる必要性も少なくなる。

早速 notion で実装してみた。fleeting と permanent は対極の性質になるから間にレビュー工程を挟むのもよさそう。literature については「誰が書いたか」を reference については「実体があるか」を判断軸にすれば運用に迷うことはないだろう。

設計

screenshot of Zettelkasten Method

実装

screenshot of Zettelkasten Method

2025-05-24 23:24:26 +0900 +0900


20250523

実践 Rust 入門 言語仕様から開発手法まで

https://www.amazon.co.jp/dp/B07QVQ7RDG

図書館で見かけて借りてきた。まだ斜め読みしかしていないが、総じて説明が丁寧な印象を持った。The Book を聖典としつつ、この本の図解で理解を補うと理解が進みそうだ。特にコード上でどう書くとメモリのスタックとヒープそれぞれに配置され、どう所有されるのかの図解は秀逸といえる。個人的には星4以上は確定なんだけど… Amazon のレビューは読者層のダイバーシティを反映していることを再認識した。

言語そのものではないがデバッガの CodeLLDB の紹介があった。個人的に GDB しか知らなかったのでこれはよい温故知新となりそう。

https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb

2025-05-23 13:21:37 +0900 +0900


20250521

嬉しい誤算

食事と運動の習慣を改めてから 60 日が経過した。結果、結果、年始には 80kg 超だった体重が 67 kgまで落ちた。予想していたよりずっと短期間での達成は嬉しい誤算だ。

減量の結果、文字通り体が軽くなった。睡眠の質があがった。あきらめていた服が再び入るようになった。よいことしかない。

次の目標は標準体重の 63.58 kg。達成すれば高校生の時と同じ体重になる。

2025-05-21 12:47:00 +0900 +0900


20250519

自己成長の記録装置

chatGPT とストック型 SaaS の Web サービスについて議論していたところ、「学習ツール」は「自己成長の記録装置」になり得るという視点を得た。これは学習ツールにとどまらず、 日記、体重管理、英単語帳、ライフログなど幅広いプロダクトに共通するテーマになる。

ピボットする時を考えてプロダクトの幅をもう少し広げて考えてみると、語彙でも、思考でも、感情でも、そこには「生きた文脈」があり、 それを記録することは成長の軌跡を形にすることとイコールになる。同時に「言葉にすること」と「書くこと」の習慣は日記同様に自己形成(自己を耕す)に大きく寄与することになる。

2025-05-19 20:39:33 +0900 +0900


20250518

Coding with AI Agent

AI 武装が遅れていた JetBrains が Junie を 4 月に一般公開したので使ってみた。試しに README.md に従って shutlle.dev へのデプロイを指示してみたところ、こちらの意図を理解したばかりか、いくつかの確認コマンドを自動的に追加してワークフローを作ってくれた。今のところ、以下の印象を持った。

Cline など他の LLM エージェントが盛り上がっていることは耳にしていたが、VSCode を普段使いしていないため乗り遅れていた。個人的にも GitHub Copilot のコード補完やチャットを使うぐらいで LLM エージェントは使ったことがなかった。慣れ親しんだ JetBrains 環境で簡単に LLM エージェントを使えるなら Cline の代わりにこちらを使用してもいいかもしれない。いつも All Products Pack を購入しているから追加の出費は不要になる(Included with All Products Pack)。

screenshot of Junie

screenshot of Pricing

2025-05-18 11:30:09 +0900 +0900


20250517

パスキーことはじめ

github の認証方法をパスキーに変更した。Google Authenticator からの6桁の数字を入れなくてもよくなったのでログインがスムースになった。

chatGPT に Chrome が使用しているパスキーについて質問してみた。

Q1 については秘密鍵はキーチェーンアクセスに保存され Chrome はそのインターフェイスとして動作するとのこと。そして iCloud を通してキーチェーンアクセスが同期されることで異なる PC/デバイス上でも同じ秘密鍵が使用可能になる。

Q2 については秘密鍵の保存場所とセキュリティ強度が主な違いになる。自分が Google Authenticator のようなソフトウェア MFA ではなくて gemalto のハードウェア MFA を使っていたのと同じ理由だった。

screenshot of chatGPT

2025-05-17 12:52:14 +0900 +0900


20250516

起業説明会

区が開催している無料の起業説明会に行ってきた。結論から言うとあまり収穫はなかった。fly.io にデプロイしているバージョンでデモを行って、ようやく、どういうサービスかを理解してもらえたようだ。事業計画書の最初にもう少しわかりやすい一枚スライドが必要かもしれない。

担当してくれた中小企業診断士の方も Freee を使って定款を作成したが、出来が一部悪く、後で作り直したとのこと。受注関係を考えれば社労士は仕事の機会をもらう代わりにかなり安いコストになっているのではないかと話し合った。

起業に際して必要な士業(行政書士、司法書士、税理士)について全く心あたりがないことを相談したら、知り合いに紹介してもらうのが一番と言われた。今度もりもとさんに相談してみよう。

2025-05-16 16:27:20 +0900 +0900


20250328

Podcast

10年ぶりに Podcast の利用を再開した。

主に散歩の時に Anderson Cooper 360 や BBC Learning English の各シリーズを聴いている。 後者は 6 分程度でエピソードやまとめまでがきれいにまとまっていて聴きやすい。語学学習者の視点での制作されていることを感じられる。 6 分ぐらいでテーマごとに細切れにしてくれたほうが、リスナーにとってもスキマ時間に聞けるし長尺動画で見失わないにいいことづくめのように思える。 でも短尺にするには編集が必要だし、うまくまとめるのも大変なのかも。

散歩中は操作をせずにだらだら聴くので長尺の番組を 2-3 本か、短尺の番組を数本事前に DL して流しっぱにするとよい。 今は STT (by AI?) で文字起こししてくれるから語学学習には本当に便利な時代になった。 スマフォでも確認できるが Web でもスクリプトが公開されているのがよい。 テクノロジーの発達によって総じて STT のコストが安くなっているのだろう。

2025-03-28 20:38:37 +0900 +0900


20250323

図書館

このところ図書館で日経と Japan Times を読むのが日課になっている。 家から徒歩5分の距離にあるのに10年間利用したことがほとんどなかった。まぁ、そんなものか。

1週間紙面を眺めていて AI の話題を見ない日はない。 SBG とマスクの 2 陣営がわかりやすく図におこされていたのがよかった。

面白いのがマイクロソフト、NVidia、オラクル、MGX などは両陣営に協力しているところ。 どちらが覇権を握ってもいいようにする強かさが見て取れる。 AI ファンドはかなり巨額(1,000億ドルから5,000億ドル)になる予想だからいかな SBG やマスクといえども単独では無理なんだろう。 データセンタのコストは電力がほぼ全て(と Eric Schmidt が言っていた)だから Arm, Ampere と省電力な部品に着目しているのは戦略として正しい。

What matters most to the computer designers at Google is not speed,
but power, low power, because data centers can consume as much
electricity as a city.

Eric Schmidt, CEO Google

https://shonan.nii.ac.jp/archives/seminar/011/files/2012/02/stein.pdf

逆に言うとクライアント側で動かすのはほぼ無理なのかなぁ。

2025-03-23 14:51:09 +0900 +0900


20241112

ドメインを親アカウントで取得するか兄弟アカウントで取得するか

メンバーアカウント: example-prd で取得したドメイン example.com を同階層の兄弟となるメンバーアカウントの example-stg, example-dev でそれぞれ dev.example.com や stg.example.com として使うのがよい。

サービスが終わる時を考えた場合 example-{prd,stg,dev} の 3 アカウントを削除すればリソースも全部消えることになる。

結論としてドメインは management account(parent account) ではなくプロダクション環境用の member account(sibling) で取得する。 主に試運転アカウントの AWS Organizations + Route53 で適当なドメインを取得して試してから、正アカウントに導入する。

Cross account subdomain delegation with Amazon Route 53

2024-11-12 22:16:42 +0900 +0900


20241109

bundler はグローバルにインストールしていい

bundle add rails するだけでグローバルにインストールしてもいい時代やったんや。手癖で –path vendor/bundle しがちだったけど、グローバルにインストールしたほうが vendor ディレクトリを git ignore する必要すらなくなるしよい。付けない派に転向する。 https://qiita.com/jnchito/items/99b1dbea1767a5095d85

.local/share/mise/installs との組み合わせがわからんけど… rbenv exec bundle exec とかしなくていいようになっているっぽいから結果良ければそれでよい。

➜ gem environment
(... snip ...)

➜ fd 'rails$' -t x /Users/kyagi/.local/share/mise/installs/ruby/ --exec ls -l
-rwxr-xr-x@ 1 kyagi  staff  549 Nov  9 15:09 /Users/kyagi/.local/share/mise/installs/ruby/3.3.4/bin/rails
-rwxr-xr-x@ 1 kyagi  staff  234 Sep 29 18:08 /Users/kyagi/.local/share/mise/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/railties-7.1.3.4/exe/rails
-rwxr-xr-x@ 1 kyagi  staff  234 Nov  9 15:09 /Users/kyagi/.local/share/mise/installs/ruby/3.3.4/lib/ruby/gems/3.3.0/gems/railties-8.0.0/exe/rails

2024-11-09 21:14:45 +0900 +0900


20241108

rails 8 GA

https://github.com/rails/rails/releases/tag/v8.0.0

solid queue を使う予定はないけれど、db を sqlite3 にしたい気持ちはある。

➜ bin/rails -T | grep solid
bin/rails solid_cable:install                # Copy over the schema and set cable adapter for Solid Cable
bin/rails solid_cache:install                # Copy over the migration, and set cache
bin/rails solid_queue:install                # Install Solid Queue
bin/rails solid_queue:start                  # start solid_queue supervisor to dispatch and process jobs

2024-11-08 08:06:45 +0900 +0900


20241106

オンボーディング

内定が決定しているインターン生をチームに迎えることになり、オンボーデ ィングについての記事を読み漁っていたところ、以下の記事が目についた。

1年で人数が倍になったエンジニアグループのオンボーディングの紹介

人が組織に加わって成果を出すまでの過程として live > learn > work > (influence) はその通りだと思う。巷でよく言われている「即戦力」の神話(?)が実現するのも、受け入れ側の準備が整っていてこそのはず。

ドメイン知識はもちろんのこと、開発標準や開発体制については分業制が主となっている昨今のチーム開発においてはチームごとにバラバラになってしまっているドメイン知識をつぎ合わせて全体像を描くのが一層難しくなっていると感じる。新メンバーに何の助けもなく自律自走を求めるのは責任放棄と言っても過言ではない。振り返って自分のオンボーディング体験を思い出してみると正直満足のいくものではなかった。ドキュメントもなく、アーキテクチャ図も使用技術一覧もなく、設計や仕様についてはメモ書き程度のものがあちこちに散らばっていて正誤もはっきりしないし、開発環境構築手順は疑問を覚える箇所が見受けられた。次の人にはそんな思いはさせたくない。

株式会社クラスEngineerオンボーディング の Notion ページも非常に参考になる。これらのフレームワークを利用してカリキュラムを作っていこう。

2024-11-06 21:58:55 +0900 +0900


20241104

はじめての技術書典

技術書典 ではじめて技術書(電子版)を購入した。 Zero to Production in Rust を stripe で支払った時をのぞけばはじめての同人誌の購入となるるため、校正/編集/校正などの点で不安もあったが蓋を開けてみれば内容は非常によかった。amazon pay での購入もはじめてだったがスムースだった。

Re:VIEW のような OSS ソフトウェアもあるし、電子版に限れば個人が書籍を出すハードルはかなり低くなってきた。売上目標のプレッシャーや在庫管理の手間もないので、個人が決めたテーマを深掘りして世に伝えるにはいい時代になった。これからも技術書典でどんどん買っていこう。

2024-11-04 21:56:28 +0900 +0900


20241029

Rails 8 は 10 月中にリリースされるか

1 ヶ月前 beta1 が、2 週間前に rc1 が出たからそろそろか。Rails 8 がリリースされたら個人開発の開発環境も追随して、かつ PostgreSQL も 1 ヶ月前 に出た 17 にしよう。 https://github.com/rails/rails/milestone/87

年内やクリスマスを意識すると世界的に秋にリリースが固まる傾向があるのかもしれない。

2024-10-29 22:52:33 +0900 +0900


20241023

個人開発のロールモデル

3 年ぐらいプレイしているゲームが今度 Android 版をリリースすることになった。 このゲームの個人開発者さんが提供しているバージョンアップ時のリリースノート、定期的に公開されるロードマップ、 note や X での発信には以前から目を通している。2 年越しで iPhone 版をリリースし、その次に 5年越しで Android 版が完成させている。 もちろんその間に機能開発や改善も絶え間なく繰り返していて、海外版のリリースもしている。 コツコツ積み上げていくその姿勢には以前から頭が下がる思いだったが改めて継続の大切さを気づかせてくれた気がする。

小さいことを積み重ねることが、とんでもないところへ行くただひとつの道だと思っています。 (イチロー)

私は以前、才能というものは一瞬のきらめきだと思っていました。 けれどもいまは、十年とか二十年とか三十年とか、同じ姿勢で同じ情熱を傾け続けられることが才能なんだと思っています。 (羽生善治)

2024-10-23 23:14:19 +0900 +0900


20241021

Stripe の審査通過

Stripe の申請が通った。前回 7/17 から 3 ヶ月ほどかかったが、こちら の 6 ページを詳細に作成し、トップページのフッタとしてリンクを載せた結果、審査に合格することができた。 以下に自分なりの知見を載せておく。

なお、上記全てにおいて日本語で作成する必要はない。 私のサービスはもともとユーザーを日本人に限定していないのとローカライズの手間を極力まで抑えるため全て英語で作成している。

これで決済機能が導入可能になったのでいよいよ Stripe の API を試用して作り込んでいく。 テストモードからはじめて、自分がユーザーになってちゃんと入金されることを確認していく予定。

2024-10-21 22:32:31 +0900 +0900


20241020

Stripe 申請 2 回目

新規にアカウントを作り直して、特商法含め、以下のページを追加して再申請した。

さて、これでどうなるか。

2024-10-20 18:21:28 +0900 +0900


20240928

iPhone16 を購入

iPhone16 256G ホワイト購入した。もりもとさんとチャットしていて、自分が iPhone の以下の機能を使っていないことがわかった。キャッチアップするためにも購入に踏み切ろう。

AI 時代に求められる能力

人により AI の活用度合いに差が出てくる。その人の知性によりリバレッジがかかるから、生産性の二極化がより一層進むのではないか。

叩き台を出す人、ゼロからイチができる人がいると、他の人がイチから拡張しやすい。とはいえ、名前のある人が出したものを叩くよりも名前のない AI が出したほうが叩きやすい AI の活用効率が言語化能力に依存するとなるとデジタルディバイドがハードやソフトだけでなくて個人によっても広がる結果となる。検索エンジンもそうだったが(いわゆるググり方) AI はより使い手の資質が求められると言える。

2024-09-30 00:11:16 +0900 +0900


20240925

mac でバックスラッシュを入力するコツ

半角英数モードでバックスラッシュを打つのに opt が必要なのがめんどくさかったが以下で望み通りにできた。結果的に、入力ソースは A ABC A 英字あ ひらがな の 3 つになったがやりたいことは実現できたのでよしとする。 https://note.com/zonu_a/n/n8d4a8eb6443c

2024-09-30 00:11:07 +0900 +0900


20240924

文章の添削と AI

15 年ほど前に lang8 という英語の日記を相互に添削するサービスを使っていた。振り返ってみると以下の点で効率がよくなかった。

「なぜ、添削してもらった書き方にするべきなのか」を説明してもらうことで、自分の英語力の成長につなげられるのがよい。

ちなみに 将棋 AI ではこの「なぜ」ができないらしい。読み書き編集に優れる claude はその点がよい

If you want an AI tool to use as a sparring partner for creative projects—writing, editing, brainstorming, or proofreading—Claude is your best bet. Your default output will sound more natural and less generic than ChatGPT’s, and you’ll also benefit from Claude 3.5’s superior coding abilities and cheaper API costs. https://zapier.com/blog/claude-vs-chatgpt/

2024-09-30 00:11:03 +0900 +0900


20240923

mac mini 式年遷宮

クリーンインストールで Ventura から Sonoma に環境を一新した。 Sequoia が 1 週間前にリリースされているが Sonoma でよい。1 年遅れで追随していく。2 周回遅れにはならないよう気を付ける。

Macintosh HD を消去して APFS でフォーマットした後にインターネットからリカバリすればよいと気軽に考えていたが、リカバリの 過程でうまくいかなくて焦った。もともと、寝る前にインストール開始まで進めてから、と考えていたが昼間に実施した方がよかった。 何回か試行錯誤したら成功したが、なぜ特定の試行で失敗したかはわからないまま。中の人も寝ていたのか、ちょうど Sequoia がリリースされてサーバが立て込んでいたのか。

mac のショートカット

「ショートカット」という機能を少し深掘りしてみた。改めてこういった知らない機能に触れる機会を強制的に設けられるのが式年遷宮がもたらす特典のひとつ。 温故知新の強制といってもいい。 Automator を GUI に近づけた、といった印象を持った。10年前に AppleScript を書いた記憶があるが、辞書アプリと Safari の英辞郎の検索をショートカットで実現できないか。

2024-09-23 19:36:58 +0900 +0900


20240922

シソーラスはもともとギリシャ語

宝物庫という意味だった claude に thesaurusphere という造語を考えたもらったがサービス名としてよさそう。th11e か t12e でもよいか。

キーボードの掃除

手持ちの 2 台の HHKB を掃除した。ずっと「掃除しなきゃな…」と感じていたストレスがなくなったのと、やっぱりキレイになると気持ちいいのとで多幸感がすごい。 所要時間はこれくらいだったと思う。寝る前に 1 - 3 を行なって、起きてから 4 - 5 をするとちょうどいい

  1. キーボードの取り外し: 5 分
  2. キーキャップの洗浄: 50 分(= 1 列 x 10分)
  3. キーボード基盤側の掃除: 30 分
  4. キーキャップの乾燥: 8 時間
  5. キーキャップの取り付け: 25 分(= 1 列 x 5 分)

HHKB モデル再考

現在は以下の 2 台を所持している。

大掃除

そろそろ大掃除の準備をしなきゃなぁ。

Maker フェア

オライリーから招待状が来ているがいったことがない。以下の文句が目についた。資本主義からこぼれ落ちる部分だよなぁ。

obsidian

obsidian 使いはじめた。いくつか有用そうな プラグイン を試してみたい。メタ情報の扱い方が Hugo と酷似しているので同期できそう。iCloud への同期とバックアップ(データエクスポート) をあとで確認する。

notion と比較して使用性(レスポンスの速さ、メタ情報付与、検索、ソフトまでの到達時間と視認性)、保守性と移植性(バックアップとリストア)に優れていると思う。

2024-09-22 16:52:28 +0900 +0900


20240921

欠けたお皿でご飯を食べるようなもの

Happy Hacking Keyboard BT のキートップを掃除していたらスペースキーにヒビが入ってしまった。 もともとスペースキーは長い面積な上に素材が繊細なので無造作にガシャガシャ洗いすぎたのかもしれない。

致命的なヒビ割れではないにしろ、なるべく直したい。 ヒビ割れしたキーボードを使うのはなんとなく縁起が悪いようにも感じる。 欠けたお皿で食事をするのと通じるものがあるだろうか。

HHKB のサイトで替えのキートップを探したところ、白と黒以外に桜色のものを発見した。 使用イメージの組み合わせ例に遊び心を見て取れる。HHKB は Twitter もはっちゃっけているし中の人が製品を本当に好きなことが伺えてよい。 https://www.pfu.ricoh.com/direct/hhkb/hhkb-option/detail_pd-kb420ktsn.html

2024-09-21 10:07:06 +0900 +0900


20240911

日本で iPhone を買う

2016年から iPhone7 を使い続けて 8 年が経った。 さすがに最近はアプリ使用中に落ちることが目立つようになってきた。 2023年で Apple のサポートから外されたこともあり、SE gen 4 か iPhone16 への買い替えを検討している。 前者は25年春まで待たないといけなそうだし、この際思い切って iPhone16 を買ってしまおうか。

過去に iPhone5, iPhone7 を購入したが、それぞれ留学やら出張先のついでに滞在先のロンドンとサンフランシスコの Apple Store で購入した。 つまり、日本で iPhone を買ったことがない。 もともと SIM フリー版が欲しかったからというのがあるが、2019年からは日本でも SIM フリーで売られているらしいから問題はなさそう。

2024-09-11 09:31:37 +0900 +0900


20240909

一般方向

謙信のように生涯勝率 97% でも一般方向が決まっていない場合、あちこちで転戦するだけで、点が線につながらない。 一方、信長は勝率は謙信ほど高くないけれど「京」という一般方向を早々に定めて邁進していた。

「“魔王”などというから、如何ほどのものかと思ったら。存外たいしたことはなかったのぉ。 あれしきの者で“天下布武”とは、わしなら天下統一も容易いな」 https://diamond.jp/articles/-/86015

この発言から、個々の戦(天下布武の武)しか見えていない感がありありと窺える。 言葉は悪いが「専門バカ」とも言える。 楽市楽座、堺掌握、海外貿易など個々の戦の背後にある無数の施策が見えていない。

「一般方向」を「選択と集中」と読み替えることもできそう。 様々な粒度で「一般方向」を決めておくことで、リソースを有効活用できる(分散させない)、 決断の速度が速くなる、目的地までのルートを意識することで結果的に所要時間が短くなる、と言えるだろうか。

自分の場合、以下のように言えるだろうか。

2024-09-09 12:46:42 +0900 +0900


20240828

mdx + astro

もりもとさんに紹介したら astro というのは割と有名なツールらしい。mdx は md の拡張だと思うけど使ったことない。

Cloudflare と AWS

Cloudflare のざっくりとした所感としては API レベルで AWS 互換となっているサービスが多く(例: AWS S3 互換の Cloudflare R2) 使いやすく、それでいてコストは低い印象を持っている。 会社としても機能拡大するために Baselime はじめ買収が目立ち、勢いが目立つ。 AWS でできることはなんでもできまっせ状態を目指しているのかもしれない。

開発環境は fly.io のほうがずっと開発者体験がよくて気に入っている。 AWS は大きくなりすぎたし万人向けになりすぎた。もっとフットワーク軽くデプロイしたい。

とはいえ、機能要件は割と AWS に並んできたけど、非機能要件はまだまだだいぶ未熟。 特に IAM, AWS Organizations, IAM Identity Center 周りは比するべくもない。

2024-08-28 22:34:30 +0900 +0900


20240825

少し幹から離れると情報が過疎になる

fly.io にデプロイしていている個人開発アプリの staging 環境が整ってきた。 以下の要素をうまく同期できているのがよい。

デフォルトだと production 環境をデプロイしようとするので、調整が必要だったが、こういうニッチな情報はネットにないので自分で試行錯誤する必要があった。 これはこれでどこかでブログにまとめておこう。

2024-08-25 21:35:26 +0900 +0900


20240823

学習とは孤独である

教育は本を読めるが、読むに値する本がどれかわからぬ人々を大量につくりだした

「はじめての統計学」(鳥居泰彦著) の序文にも「学習は孤独である、自分も今孤独な作業をしている、みなさんも孤独に慣れてください」という 序文があったのを思い出した。この言葉に出会ったのは大学時代だが、 この序文だけで価値がある。

2024-08-23 09:44:12 +0900 +0900


20240819

時間の使いかたで主と副が逆転している

休日に個人開発を進めているものの、このごろ、あまり集中できていない。 言い換えると、開発の合間にアニメやゲームをしているのではなく、アニメやゲームの合間に開発をしているスタイルになっていることが多い。 もちろん常に集中して生産性が高い状態でいることは難しいし、だらだらでもやらないよりはずっとましなのだが。

生産と消費の割合とも言える。人生で何かを生産したいのか、消費したいのか。 15分でも割とできるタスクは多い。AWS で rails の IAM を作ったり cognito の設定をしたり。 時間さえかければ必ず前に進む作業を織り交ぜながら進めて行った方がよいのかもしれない。

質は量をこなすことしか生まれないし、自分のような凡人ななおさらかけた時間と成果は比例することがほとんど。 何かにうまくなりたかったり、成し遂げたいと思ったら単純に量を増やすしかない。 量を増やすにしてもまとまった時間を割くというよりも細かい時間を積み上げていくほうが現実的。

「次に何をやるか」いわば設計はトイレやお風呂の時でも進められる。 手を動かさない時でもメタ的に進捗はあげられる。これも結局は「どれだけ考えているか」という思考の量。 つまり量をこなすしかない。

2024-08-19 23:53:06 +0900 +0900


20240817

愚者は経験に学び、賢者は歴史に学ぶ

「真似」から「理解」へのステップが創造力を培う基礎になる(羽生善治)

Rust に限らずプログラミング力を底上げしたくて https://www.howtocodeit.com/ をちょくちょく読んでいる。 将棋に限らずほとんどの分野では「学ぶ」とはまず「真似ぶ」ところからはじまると思う。 「守破離」でも「巨人の肩に乗る」でもいいが、最初の段階ではまず真似をして正しい「型」を身につけることから。

「我流は無型」が通用するのはごくごく一握りの天才のみで、ほとんどの人にとって我流は学習効率が悪すぎると思う。 「愚者は経験に学び、賢者は歴史に学ぶ」。短い人生で愚者パターンで学んでいたら何も成し得ない。 学習のしかたを学ぶ、というメタ的な方法論も興味があるが、それはまた別の話。

2024-08-17 09:28:41 +0900 +0900


20240814

ワンライナと爪楊枝群症候群は揮発性のコード

シングルクォートが含まれるフィールドを INSERT するのにひさびさの爪楊枝群症候群(leaning toothpick syndrome) を発動してしまった。 DB に入ればいいんだよ。入れば。

開発環境だからと傍若無人な振る舞いを許している。

  1. postgresql から export して
psql> COPY chartulas to '/tmp/chartulas.csv' delimiters',';
➜ sort -k1 -n /tmp/chartulas.csv | less
  1. rails で特定のテーブルのみを初期化して auto increment のカウンタもリセットしてから
irb> Chartula.delete_all
irb> ActiveRecord::Base.connection.reset_pk_sequence!('chartulas')
  1. import の SQL を乱暴に作成して(シングルクォートは double them up しろ というのを初めて知った)
$ ruby -r csv -e "CSV.parse(ARGF.read, headers: true) do |row| row[1].gsub!('\'', '\'\''); row[2].gsub!('\'', '\'\''); row[3].gsub!('\'', '\'\''); puts \"INSERT INTO chartulas VALUES (DEFAULT, 1, \'#{row[1]}\', \'#{row[2]}\', \'#{row[3]}\', \'#{row[4]}\', \'#{row[5]}\');\"; end" /tmp/chartulas.csv > /tmp/insert.sql
  1. import する
psql> \i /tmp/isert.sql

ながらく MySQL の住人だったからか Postgresql の \X 記法にどうしても違和感を感じてしまう。徐々に慣れていくしかない。

2024-08-14 23:49:03 +0900 +0900


20240813

「コード読めばわかるんで」という人は危険人物

New Type Pattern の記事を読んでいて、思わず膝を打ってしまった。 経験から「コード読めばわかるんで」という人は brilliant jerk 気質の人に多い気がする。

When asked what their test function tests, this teammate might tell you, "just read the code". 
This individual is dangerous, and should be treated with the same fear and suspicion you reserve for C++.

https://www.howtocodeit.com/articles/ultimate-guide-rust-newtypes

戦わずして勝つ、ではないけど、コードを読まずしてドキュメントや図でわかるんだったらなおさらいい。

2024-08-13 23:07:13 +0900 +0900


20240810

サクナヒメの音楽と機会

田植え唄と ED テーマの音楽がよい。 民謡調の歌手の方が歌っているのだが、ゲームとの親和性が素晴らしい。 こういう人を見つけてプロデュースする機会もゲームやアニメにおけるメディアミックス戦略のひとつ。

私の親戚にも十代の頃から民謡をしていていくつもの大会にも出ていたお姉さんがいるが、就職はうまくいかず民謡の先生をしている。 もしかしたら彼女にもこういった機会があったかもしれないと思うと歯がゆい。 民謡の歌手だから民謡の世界を探索することはもちろん重要だが、そこにゲームなど別の分野の掛け算をすることで機会が拓けるのかもしれない。

2024-08-10 03:34:20 +0900 +0900


20240808

beta 0.5 でするグラウンドワークに rubocop を入れる

ちょうどよい記事を見つけたので beta 0.5 の作業に入れておく。

継続的にRailsアプリを開発する上で早めにやっておきたいこと

開発の標準プロセスを最初に整備しておくと恩恵が大きい。逆に最初が「ぐだぐだ」だと後から軌道修正するのは難しい。 その意味でも最初の設計やワークフローの整備は経験のあるエンジニアが行うべきだと思う。

次からは 2 回目になります

「まずは 1 回やってみてください。次からは 2 回目になります」は蓋し名言だと思う。ただし、進次郎が言ったわけではない。

物体は摩擦の関係で動き出す時が最もエネルギーを必要とするのと似ている。 「まずは 5 分やってみてください。少なくとも 5 分はやったことになります」だと響かないか。難しいな。

天穂のサクナヒメ

アニメを見始めた。なかなかよい。どこがいいのか、説明が難しい不思議な魅力がある。 「やればできる子」のサクナヒメの成長はもちろん、どこか日本の原風景の描写に惹かれるのかもしれない。 異物として外国人のミルテを入れているところは閉鎖的になりがちな日本文化に客観性を導入したのかもしれない。 前から名前だけは聞いていたけど、ゲームもプレイしたくなってきた。

2024-08-08 21:55:45 +0900 +0900


20240805

アルファ版のユーザーのペルソナ

個人開発している Web アプリのアルファ版のユーザーを探している。 コアなユーザーを 10 人、いや 3 人ほど集めたい。 以下に該当する人たちを想定している。

具体的なペルソナとしてはこんな人たちだろうか。

私は、語学学習の中では単語力強化にとてもこだわっている。外国語能力(とくに読解力)と語彙力には
高い相関関係があることが実証されており、語彙力を伸ばせば外国語能力も飛躍的に伸びる可能性が高いといえる。

単語は理屈抜きに覚えるしかなく、日本にいながらネイティブの読解力に近づこうと思ったら
ただひたすら知らない単語をしらみつぶしに覚えていく努力をするしかない。

ロンドン大学の遠隔教育を受けたとき、課題図書に難易度の高い英単語が頻出しているのに気づき、
ネイティブの若い学生たちがこんな難解なテキストを読んでいることに度肝を抜かれた。
英検1級に合格したことで満足し、語彙力強化を怠ってしまったら、大学の指定図書さえ十分に読めないことを
思い知ったのだ。そしてこのとき私は「一生語彙力を磨き続ける」と強く心に決めた。
ネイティブ並みの語彙力をつけるには、それほどの鍛錬が欠かせないのだ。

<https://serai.jp/hobby/1060906#google_vignette>
これは、我々通訳者が作る単語帳です。お見せするのも恥ずかしいんですが(笑)。
これはビル・ゲイツさんの通訳をさせていただいたときの単語帳で、本当に恥ずかしいんですが……
こういうもの(英単語が書き込まれているExcelのシート)を毎回作ります。

私は18年間通訳の仕事をしていますが、すべての英単語を覚えるなんていうことはムリです。
ですから、毎回新しい言葉を覚えていますし、このように単語帳というものを作るんですね。
でも、それでもやっぱり完璧にはなりません。

<https://logmi.jp/business/articles/322640>

橋頭堡としてのファーストアプリ

たとえ、誰も使わなかったとしても、自分が使うから開発は継続していく。 少なくとも自分の英語力強化には役立っているという点では価値がある。

また、開発を通して得た経験値も大きい。 認証/決済といった機能やプライバシーポリシー/利用規約などの汎用性が高いパーツについては 今後の開発で共通して使用できる。結果、開発効率が向上する。 インフラ面としては AWS Organizations + IAM Identity Center の運用の道筋が見えたことや 開発/ステージング環境として fly.io へのデプロイするノウハウが得られた。

個人開発は超ニッチで勝負し、売上を目指さない

「エンジニアが開発したアプリは自己満足で自分だけが使うアプリになってしまう」類のことを 耳にすることがあるが、それでいいのではないだろうか。少なくとも、ひとり、自分というユーザーの 問題を解決できているのであれば、それだけで価値がある。そのエンジニアの感覚がよほど他者と かけ離れていない限り擦り合わせるのはそんなに難しくはないはずだ。

git もこういったアプローチのもと作られたと認識している。 振り返ってみると、こんな超難解なツールがよく流行ったものだと思うが、根本的な問題を解決しているのであれば 多少使い方やインターフェイスが独特だろうが一般化はしやすい。

個人開発のもうひとつのよいところは売上を目指さなくていいということだ。 これは、ターゲットとなるユーザーを選べる、と言えるかもしれない。 「この問題に対する私の解はこうだけど、よかったらあなたも使って」的なアプローチは OSS の基本だ。 無理に大衆に迎合したプロダクトを作ることは強みを希釈することにつながる。

最後に、売上の必需性。例えば売上が1万5,000円とか。50万円という額は僕らからするとすごく高いですよね。
良いなって思います。けれども、スタートアップからすると、50万円じゃ会社が成り立たないですよね。

ということで、じゃあ個人開発者がどうやって生きたらいいかなんですが、つまり売上がそこまで高くない、
リスクがある分野には、ライバルがまず少ないと思っています。

https://logmi.jp/tech/articles/330120

2024-08-05 11:40:24 +0900 +0900


20240802

歩くことが大事

このごろは、暑いのと開発に時間を割いているのとで、朝の散歩が疎かになっていた。 そのせいか、体重が増加傾向になってしまった。

日光を浴びるという点でも、忙しくても散歩はするようにしよう。 歩きながらいろいろ思考の整理もできるし。

何気に shuttle.rs にデプロイしている statscribe が記録用に役立っている。 普段使いする API はこういうのでいいんだよ、こういうので。  

$ xhs get -b statscribe.shuttleapp.rs/stats/${token}/all | jq -cr '.[] | select(.tag == "scale")'
{"id":1,"stat":77.4,"tag":"scale","datetime":"2024-07-01T09:05:40.845351+09:00"}
{"id":9,"stat":77.2,"tag":"scale","datetime":"2024-07-02T03:51:50.376971+09:00"}
{"id":10,"stat":76.7,"tag":"scale","datetime":"2024-07-03T03:28:54.172793+09:00"}
{"id":16,"stat":76.2,"tag":"scale","datetime":"2024-07-04T05:12:43.866092+09:00"}
{"id":17,"stat":77.2,"tag":"scale","datetime":"2024-07-05T04:44:45.235495+09:00"}
{"id":18,"stat":78,"tag":"scale","datetime":"2024-07-06T04:42:20.911373+09:00"}
{"id":20,"stat":78.3,"tag":"scale","datetime":"2024-07-07T03:37:12.576454+09:00"}
{"id":21,"stat":78.3,"tag":"scale","datetime":"2024-07-07T09:01:28.056666+09:00"}
{"id":22,"stat":78,"tag":"scale","datetime":"2024-07-08T04:54:09.465264+09:00"}
{"id":23,"stat":77,"tag":"scale","datetime":"2024-07-09T05:22:51.127532+09:00"}
{"id":24,"stat":76.4,"tag":"scale","datetime":"2024-07-10T05:04:37.611616+09:00"}
{"id":25,"stat":77,"tag":"scale","datetime":"2024-07-11T04:43:52.913890+09:00"}
{"id":26,"stat":78.1,"tag":"scale","datetime":"2024-07-12T05:35:25.985414+09:00"}
{"id":27,"stat":77.4,"tag":"scale","datetime":"2024-07-13T04:59:01.999598+09:00"}
{"id":28,"stat":77.7,"tag":"scale","datetime":"2024-07-14T04:23:18.075916+09:00"}
{"id":29,"stat":77.1,"tag":"scale","datetime":"2024-07-15T06:11:50.229005+09:00"}
{"id":30,"stat":76.9,"tag":"scale","datetime":"2024-07-16T06:45:28.790132+09:00"}
{"id":31,"stat":77.7,"tag":"scale","datetime":"2024-07-17T05:46:38.295156+09:00"}
{"id":32,"stat":76.7,"tag":"scale","datetime":"2024-07-18T07:10:00.187350+09:00"}
{"id":33,"stat":77.3,"tag":"scale","datetime":"2024-07-19T05:11:34.686213+09:00"}
{"id":34,"stat":76.7,"tag":"scale","datetime":"2024-07-20T07:08:06.165706+09:00"}
{"id":35,"stat":77.6,"tag":"scale","datetime":"2024-07-21T04:01:30.638578+09:00"}
{"id":36,"stat":78,"tag":"scale","datetime":"2024-07-23T06:06:49.346260+09:00"}
{"id":37,"stat":77.7,"tag":"scale","datetime":"2024-07-24T04:01:44.228581+09:00"}
{"id":38,"stat":77.7,"tag":"scale","datetime":"2024-07-25T04:49:49.478899+09:00"}
{"id":39,"stat":78.2,"tag":"scale","datetime":"2024-07-26T06:07:19.482083+09:00"}
{"id":40,"stat":78.4,"tag":"scale","datetime":"2024-07-29T05:50:16.527464+09:00"}
{"id":41,"stat":78.8,"tag":"scale","datetime":"2024-07-30T04:06:31.847886+09:00"}
{"id":42,"stat":78.5,"tag":"scale","datetime":"2024-07-31T06:14:20.245091+09:00"}
{"id":43,"stat":78.3,"tag":"scale","datetime":"2024-08-01T05:34:16.283147+09:00"}

2024-08-02 06:17:42 +0900 +0900


20240730

タップでトグルされる KPI

fitbit をタップすると現在日時が 2339 30日 火 のように表示される。 最近のアップデートでさらにこの下の 1 行に消費カロリー、歩数、心拍数が表示されることに気がついた。

タップごとに絵文字と数字の組み合わせが切り替わるようになっている。これはよい UI。 ❤️65 → 👞 12,845 → 🔥 2813

継続の指標となる数字をさりげなく表示するという点は個人開発にも活かしたい。 とりあえず開発中のアプリのロゴの右に単語数を表示するようにしてみた。

screenshot of rails app logo

2024-07-30 23:36:27 +0900 +0900


20240728

Postgresql では auto_increment が効かない

rails db:reset && rails db:migrate してから Model.create() すると id が入るけど、 既存のデータをリストアすると id が nil になってしまう問題に悩まされている。 これでもダメ。

  def change
    remove_column :mytables, :id
    add_column :mytables, :id, :integer, primary_key: true, null: false, autoincrement: true
  end

この例を参考に .maximum(:id).next.to_i したらリストアしてからも id が入るようになったけど こんなんが本当に必要なのか? auto increment は MySQL の方言とかいう人もいるし。もう少し調べてみるか。

https://stackoverflow.com/questions/40545281/autoincrement-postgre-db-id-field-in-rails

2024-07-28 23:49:01 +0900 +0900


20240727

PostgreSQL のダンプデータからテーブル名を別名にしてリストアする

既存の Rails アプリをいちから作り直しているうちに、だいぶ形になってきた。 すでにデータは既存のアプリにあるので、そちらからテーブル名を別名にしてリストアする方法を探していたが、以下に落ち着いた。 既存のテーブル名を sources 新規のテーブル名を destinations とする場合、一度別名でテーブルのコピーを作成する。 その後ダンプしてリストア時に別名にしたテーブルを指定すればよい。

> CREATE TABLE destinations AS SELECT * FROM sources;
➜ pg_dump -f db/development.dump.bin.postgres ${db} -Fc
➜ pg_restore -c -U rails -W -d [PROJECT_NAME]_development -t destinations development.dump.bin.postgres

2024-07-27 23:02:20 +0900 +0900


20240725

さようなら dotenv, こんにちは Encrypted credentials

The Complete Guide to Ruby on Rails Encrypted Credentials を読んで 認証情報の保存場所を .env から config/credentials/development.yml.enc に切り替えた。 Rails における認証情報の取り扱いの新標準だと思う。

この変更により rails アプリから認証情報を参照する方法も変わることになる。

screenshot of diff

同時にマスターキーも config/credentials/development.key になる。 これにより既存の config/credentials.yml.enc と config/master.key は不要になるので削除してしまってよい。環境ごとの認証情報と鍵は以下のコマンドで生成できる。

➜ EDITOR="vi" rails credentials:edit --environment=development

これで dotenv とさよならできるかと思ったが、AWS SDK にホームディレクトリ配下 .aws/{config,credentials} の認証情報を読みにいかせないための AWS_SDK_CONFIG_OPT_OUT だけは必要になる。これだけなら認証情報でもなんでもない。いままでは .gitignore でコミットしないとはいえ .env に平文で書かれていた認証情報が気になったが今後はそういう こともなくなるので精神衛生上もよい。

➜ cat .env
AWS_SDK_CONFIG_OPT_OUT=true

新旧を比較すると以下のようになる。development.yml.enc と development.key は環境ごとに stagingproduction と読み替えることが可能。

いままで これから
提供元 rubygem: dotenv rails 標準機能
認証情報の格納ファイル .env config/credentials/development.yml.enc
復号に使用する鍵 config/master.key config/credentials/development.key
rails アプリから認証情報を参照する方法 ENV[‘AWS_ACCESS_KEY’] Rails.application.credentials.dig(:aws, :access_key_id)
レポジトリへコミットするファイル なし config/credentials/development.yml.enc
レポジトリへコミットせずチームで共有するファイル(パスワード管理ツールなど) config/master.key config/development.key

2024-07-25 21:09:01 +0900 +0900


20240724

FIXME with types

個人開発では割と「緩い(loose)」コミットを許容している。 仕事だともう少し推敲したりするようなところでも FIXME コメントとともにコミットしてしまうことが多いが 個人開発は継続性に重点をおいてこのようなスタイルにしている。Conventional Commits ならぬ Conventional FIXME と言えるかもしれない。

そんな感じでコミットを重ねていくと自然と FIXME が増えていくことになるが、そのうち FIXME もいくつかの種類に分類できることに気がついた。 Conventional Commits 同様、FIXME にも「型」を導入すると理解や検索の 点でよいかもしれない。

screenshot of rails error message

現在、思いつくのはざっと以下の通り。HANDLE ERRORS, O11Y(Observability), NEED TEST は機能が 一通り整ってから取り掛かるなど自分なりの開発方針を立てると、完璧主義の罠にも陥らずにすむし nitpicker にもならずにすむ。

Rails にはサブコマンドの notes があるが、単純に FIXME の文字列で検索して表示しているわけではないようだ。

$ bin/rails --help | grep notes
notes                              Show comments in your code annotated with FIXME, OPTIMIZE, and TODO

$ bin/rails notes
app/controllers/auth_controller.rb:
* [55] [FIXME] WRITE BETTER
* 

$ rg FIXME 
app/controllers/auth_controller.rb
55:    # FIXME: WRITE BETTER

app/views/chartulas/_chartula.html.erb
13:      <%# # FIXME: NOT WORK %>

app/views/application/_outside_pages_navbar.html.erb
50:          <!-- # FIXME: HARD CODING -->

app/views/application/_inside_pages_navbar.html.erb
28:          <!-- # FIXME: HARD CODING -->

app/views/layouts/application.html.erb
13:  <!-- # FIXME: toggle_light_and_dark_mode
26:<!-- # FIXME: toggle_light_and_dark_mode

自分なりの開発プロセス標準

同様に、 自分の中で開発プロセス標準を定めておくと無理に進捗に焦らなくてよくなる。 5. Groundwork 時の Refactoring 時に集中して FIXME を直すと決めておけば精神衛生的にも気持ちの整理がつく。 例えば、私の Web サービスの開発プロセスの標準は以下の順番がベストプラクティスになっている。

Id Focus What to develop Implementation
alpha 0.1 PoC A Few Core Feature CRUD
alpha 0.2 Marketing Outside Pages Landing pages, Deploy procedure I
alpha 0.3 Initial Stage I Authentication, Multi users Signup, Login, Logout, Session
alpha 0.4 Initial Stage II Inside Pages Navbar, Footer, Search, Pagination
PMF Product Market Fit Listen to Feedbacks
beta 0.5 Groundwork Lint, Test, Refactoring Rubocop, Factory bot, Unit Test, CI, System Test
beta 0.6 Availability Backup, Restore Scheduled jobs, Deploy procedure II
beta 0.7 Paperwork Legal Pages Privacy Policy, Terms of Service
beta 0.8 Payment Subscriptions Stripe
beta 0.9 Observability, Capacity Planning Log, Trace, Metrics Log, Trace, Metrics, Load balancing, Scaling
ga 1.0 Bug fix

2024-07-24 22:08:05 +0900 +0900


20240723

暗黙の優先順位

Cognito のためにクライアントを作成する時に dotenv を使用して 認証情報を Rails アプリに ロードしているのにそちらを使わずに aws configure sso の値を使っているために IAM Identity Center(sso) のセッションが切れると Aws::Errors::InvalidSSOToken になってしまっていた。

screenshot of rails error message

これは AWS SDK が認証情報を参照する優先順位として、まずホームディレクトリにある ~/.aws/{config,credentials} を 優先してチェックしてしまうからだった。AWS_SDK_CONFIG_OPT_OUT=true にしておけばこの問題は解決する。 fly.io では発生しないだろうし、こういう環境依存の問題が最もわかりにくい。

The shared config file is not checked if the environment
variable AWS_SDK_CONFIG_OPT_OUT is set.

https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html

2024-07-23 22:01:55 +0900 +0900


20240722

どの Web サービスにも必要な 2 つの機能

認証と決済。以前からこの 2 つの機能を自分で作れるようになりたいと考えていた。 この 2 つは一度作ってしまえば、ほぼ全ての Web サービスで使いまわせるので投資対効果が高い。 多産多死で打率1割どころか3厘(「せんみつ」と呼ばれる)ぐらいの新規事業で真っ先に共通化したい部分だと思う。

2024-07-22 23:28:34 +0900 +0900


20240721

AWS Cognito Hosted UI

個人開発しているアプリの認証基盤に AWS Cognito を使用するため、土日に弄んでいた。 最初は SDK 経由での実装を試みていたが、ネット上にあまり例が見つからないのと、手順が煩雑な印象を受けていて諦めそうになっていたところ、 YouTube の動画で Hosted UI の機能を知った。 フォーム自体を AWS が生成してくれるのでアプリが acc/pass を全く触ることなく認証を完了できるのがよい。

Hosted UI でコールバックされた後にどうすればいいのかが不明だったが AWS 公式ブログのこの記事の Authorization code grant の通りにやってみたら 無事にユーザープールにアクセスすることができた。Rails アプリとしては UUID で管理されているユーザー ID を Users テーブルに格納するだけでよい。 個人開発者にとって 認証基盤など個人では手に負えない分野は巨大テックの企業努力を利用させてもらう のが正しいアプローチだと思う。

4. After Amazon Cognito verifies the user pool credentials or provider
tokens it receives, the user is redirected to the URL that was specified in
the original redirect_uri query parameter. The redirect also sets a
code query parameter that specifies the authorization code that was
vended to the user by Cognito.

5. The custom application that’s hosted at the redirect URL can then
extract the authorization code from the query parameters and exchange
it for user pool tokens. The exchange occurs by submitting a POST
request to https://AUTH_DOMAIN/oauth2/token with the following
application/x-www-form-urlencoded parameters:

- grant_type – Set to authorization_code for this grant.
- code – The authorization code that’s vended to the user.
- client_id – Same as from the request in step 1.
- redirect_uri – Same as from the request in step 1.

https://aws.amazon.com/blogs/security/how-to-use-oauth-2-0-in-amazon-cognito-learn-about-the-different-oauth-2-0-grants/

curl で 5 の HTTP POST リクエストを作成すると以下のようになる。

➜ curl -X POST https://<MYDOMAIN>.amazoncognito.com/oauth2/token
-H 'Content-Type: application/x-www-form-urlencoded'
-d "grant_type=authorization_code&code=<CODE>&client_id=<CLIENT_ID>
&redirect_uri=http://localhost:3000/auth/callback"

Rails の AuthController#callback の実装コードはベタに書くと以下のようになる。

class AuthController < ApplicationController
    def callback
        code = params[:code]
        uri = URI("https://<MYDOMAIN>.amazoncognito.com/oauth2/token")
        req = Net::HTTP::Post.new(uri)
        req.content_type = 'application/x-www-form-urlencoded'
        req.set_form_data("grant_type": "authorization_code", 
          "code": "#{code}", "client_id": "<CLIENT_ID>", 
          "redirect_uri": "http://localhost:3000/auth/callback")
        res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') do |http|
            http.request(req)
        end
        
        tokens = JSON.parse(res.body)
        client = Aws::CognitoIdentityProvider::Client.new(... snip ...)
        cognito_user = client.get_user({ access_token: tokens["access_token"] })
        cognito_user_id = cognito_user.username # UUID
        
        user = User.where(cognito_user_id: cognito_user_id).first
        if user.nil?
          user = User.create(cognito_user_id: cognito_user_id)
        end
        session[:cognito_user_id] = cognito_user_id
        redirect_to home_path, notice: "Signed up successfully"
    end
end

Firebase Authentication vs AWS Cognito

ネットではよく Firebase Authentication との比較記事があるが、どれも的を得ていないものばかりなのと サンプルコードも Hosted UI を対象にしたものを見つけることができなかった。 記事の内容も浅いものがほとんどで、意図せず shallow end の情報ばかりが過剰供給されているネットの特性を再認識することになった。 少し時間はかかったが、 そのぶん、今回はコピペではなく仕様から理解することにつながったので、結果的にはよかったと思う。 結局、自分の手を動かして理解したり検証する以上に信頼できるのものはない。

Firebase Authentication に不満があるわけではなく、実際に開発環境では長らくこちらを使用していたが、本番環境は AWS におくことを考えているため 認証機能だけ別クラウドになってしまうことにもやもやを抱えていた。今回 AWS Cognito の認証機能の検証が確認できたため、 アカウント管理(AWS Organization + Identity Center) やオブザーバビリティ(Cloud Watch)、 実行基盤(App Runner + RDS) を含めて AWS に集約できる目処が立ったのが長期的にはプラスになってくると思う。

2024-07-21 15:50:49 +0900 +0900


20240720

ガーブルバンドクライ

2 週間ほど前に見始めたアニメですっかりハマってしまった。それから何周かしているが観るたびに面白い。 正直なところ、見慣れない CG アニメということもあり、1 話目の時点では全く面白さを感じなかった。 それが 3 話目ぐらいから俄然面白くなってきて、 最終話の時点で自分の中の アニメランキングの中でも歴代トップを争う高評価となった。 見慣れなかった CG もいつのまにか馴染んできたばかりか、ライブシーンでの立体的なカメラワークなど CG だからこそ成し得た演出もあると気がついた。

全話を通して、主人公のエネルギー、aka トゲトゲ、が心に突き刺さる。 行き場のないドロドロした熱量。空回り。すれ違い。 ああ、そうだ、十代の頃ってこんな感じだったよなぁ。

仁菜「ああゆう子は反撃できないようにしっかり仲間作ってから仕掛けてくるんです。
     仲間使って無視して、危害加えてきて。
     あたし、病院に運び込まれたのに、学校どころか家族まで "騒ぎにしない方がいい" って」
桃香「やっぱり歌った方がいいと思うぞ。今の話だけでも 5 曲は作れる」
桃香「それだけ仁菜は鬱屈して、エネルギーが、溜まってる。それは...紛れもない、ロックだ。」
仁菜「...ロック?」
桃香「誰もお前のことを知らないし、誰も待ってやしない。でも、それが面白いんだろ?」
仁菜「ァーアーアーーアーーアアアアアアアーーーーーーー!!!!!!」
桃香「仁菜はロックンロールなんだよ」

私ももともと社会不適合者で、十代後半からはずっと死にたいと考えていて、働いてからも、葬式代は稼いで貯金しておかないといけないなぁという 気持ちだけで働いていた。三十歳になったら死ねばいいから、それまでは好きなコンピュータを弄んで生きていればそれでいいやと刹那的に生きていた。 それが、いつのまにやら少なからず処世術を身につけた(身についていない)いっぱしの大人になっていたんだなあ(なっていない)。

年を重ねていくうちにいつの間にか鬱屈さをごまかして、擦り減って、エネルギーが枯渇していた。 音楽ってこんなにエネルギーを伝播させるものなんだということを初めて実感したかもしれない。

作中で展開される曲はもう全部いい曲ばかりだけど、トップ 3 を選べと言われたら(言われてない) 「視界の隅 朽ちる音」「空白とカタルシス」「名もなきなにもかも」「爆ぜて咲く」「雑踏、僕らの街」だろうか(4 つじゃねーか)。 特に「視界の隅 朽ちる音」の歌詞は響く。だらだらと年齢を重ねてしまって、このままだと死ぬまで願いは叶わないかもしれない。 自分の音を朽ちさせてはいけない。そのまえにやるだけやってみるかという気になる。

視界の隅 朽ちる音

そうやって 知らないフリで
僕ら手が汚れないように
視界の隅 崩れてゆく夢のかけら
気づかないフリして 聞こえないフリして
ほら 過ぎてゆく

(... snip ...)

灰になった後で ようやく気づいて
願いはいつまでも届かない
変わり続けるこの世界で
僕ら 何を浮かべようか

(... snip ...)

何を掲げようか
君に会えるだろうか
全て終わる前に
この指で 描いていこう

自分の中のトゲトゲを折りながら、妥協しながら、生きていくことが普通になってしまった私にとって大きな「爪痕」を残したアニメとなった。 ロックっていいな。

2024-07-20 22:46:55 +0900 +0900


20240719

Linux の man セクションの分類方法を転用する

Warp の notebook にコマンドの snippet などをナレッジとして少しずつ書き足していくうちに次第に煩雑になってきた。 どうやって整理したものかと考えたところ、Linux の man ページに倣って独自に 1 から 9 のそれぞれの数字にカテゴリを定義し、 分類していくことにした。

0 から 9 の数字に種類としての意味を持たせて分類するやりかたは図書分類法に代表される歴史的な方法だが、人間が処理することを想定しているはず。 コンピュータにはまた別のやりかた(10進数ベースではなく2進数ベース)もありそう。 ただ、Warp を操作するのは人間である自分だからなぁ。

3. Framework Manual には rails や hugo 関連を、4. Saas Manual には AWS 関連(CLI, SDK, Cloud Formation) をはじめ fly.io や shuttle.rs で提供されている CLI を 含めていく。

自分のナレッジとしてのセクション

1. General Commands Manual
2. Programming Manual
3. Framework Manual
4. SaaS Manual
5. Formats Manual
6. Project Manual
7. Miscellaneous Information Manual
8. System Manager's Manual
9. Side project Manual

Linux の man ページのセクション

$ man man
(... snip ...)
     The sections of the manual are:
           1.   General Commands Manual
           2.   System Calls Manual
           3.   Library Functions Manual
           4.   Kernel Interfaces Manual
           5.   File Formats Manual
           6.   Games Manual
           7.   Miscellaneous Information Manual
           8.   System Manager's Manual
           9.   Kernel Developer's Manual

screenshot of warp terminal

2024-07-19 00:03:17 +0900 +0900


20240718

自由度の高さが心地よい Hugo

シンプルかつ拡張可能な設計が素晴らしい。プログラマ向けの静的サイトジェネレータといったところ。 Template と Method を少し触った程度だが自由度の高さが心地よい。 ブラウザからではなく生のファイルに対して grep をはじめ *NIX 環境のツールが使用可能な状態にしておくのは 検索、置換、といった編集上でも、バックアップといった運用上でも恩恵が大きい。

とりあえずランディングページにコンテンツを連続して表示するようにしてみた。 コンテンツごとの区切りがわかりやすいようにインラインで色づけしている。

layouts/_default/home.html

{{ define "main" }}
  {{ range where $.Site.RegularPages "Section" "posts" }}
    <h3 style="background: linear-gradient(to right, #33ccff, #66ccff, #ccccff, #ffccff);
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;">
      {{ .Title }}
    </h3>
    {{ .Content }}
    <p style="text-align: right">{{ .Date }}</p>
    <hr/>
  {{ end }}
{{ end }}

Multilingual mode の設定もしてみた。 選択可能なオプションとして Translation by file nameTranslation by content directory があるが後者を選択している。 どちらを選んでも設定した言語でパス依存の自動リンクが生成される。 せっかくなので 日本語 の時はダークモード、 英語 の時はライトモードにした。 このマルチリンガル設定は通訳者や翻訳者の学習プロセスにも使用できるのではないだろうか。 まだ未対応の有用な設定項目もあるのでいろいろ試したい。.IsTranslated は切り分けに使用できそう。

テーマは typo を使用している。シンプルかつ洗練されたデザインが良い。 Setup wiki の hugo.toml を使う場合、ローカルの Mac では問題なくビルドできていたのだけれど Cloudflare Pages ではエラーになってしまったので issue で報告しておいた。 https://github.com/tomfran/typo/issues/7

勢いを感じる Cloudflare

仕事で Google Cloud Storage の移行先として Cloudflare R2 を使用したことがきっかけで使い始めたが、なかなかよい。 特に AWS とは API レベルで互換性を保っているサービスもあり(S3)、SDK や CLI がそのまま使える。 自分の中では勝手に AWS の弟分のようなポジションの印象を持っている。 今年に入ってからPartyKit, Baselime, BastionZero と矢継ぎ早に買収を進めている。現在、最も勢いを感じる企業のひとつ。

静的ウェブサイトの構築には個人開発している Web サービス用に AWS Amplify も使用しているが、Cloudflare Pages とこれといった違いはない。 強いて言えば前者はパスワードによるアクセス制限が可能なことぐらい。 Route53 でドメインを取得しているのでカスタムドメインを使用するにあたって同じクラウドサービスを使うほうがスムーズというだけ。 そのうち Cloudflare でドメインを取る日も近いかもしれない。

2024-07-18 01:26:02 +0900 +0900